Linux --Look around copy_mm ()



I read it to get a feel for the difference between multi-process / thread, so I summarized it. See version read 5.4 torvalds/linux

Threads and processes in Linux

Green threads / native threads

Threads scheduled by virtual machines rather than the OS. Emulate a multithreaded environment regardless of OS functionality.

The OS scheduler schedules thread execution (Can be displayed with -L in the ps command)

(Digression) Story of thread model

M: N thread is an asymmetric thread model in which the kernel thread is M and the user thread is N. Operates by mapping multiple kernel threads to multiple user threads It seems that golang uses this and the switch cost is very low.

I looked at the kernel source

Basically, both fork (2) and pthred_create () internally call do_fork (). clone calls do_fork after it is called. It seems that the difference between process and thread creation is distinguished by the difference in the flag when calling this do_fork ().

long sys_clone(unsigned long clone_flags, unsigned long newsp,
	       void __user *parent_tid, void __user *child_tid)
	long ret;

	if (!newsp)
		newsp = UPT_SP(&current->thread.regs.regs);
	current->thread.forking = 1;
	ret = do_fork(clone_flags, newsp, &current->thread.regs, 0, parent_tid,
	current->thread.forking = 0;
	return ret;

Outline of processing flow

do_fork()_do_fork()copy_process()copy_mm()dup_mmap () (If it is not LWP, process cow below) ⑥ copy_page_range()copy_one_pte () Copy vm area from one task to another

static int copy_mm(unsigned long clone_flags, struct task_struct *tsk)
    struct mm_struct *mm, *oldmm;
    int retval;

    tsk->min_flt = tsk->maj_flt = 0;
    tsk->nvcsw = tsk->nivcsw = 0;
    tsk->last_switch_count = tsk->nvcsw + tsk->nivcsw;
    tsk->last_switch_time = 0;

    tsk->mm = NULL;
    tsk->active_mm = NULL;

    oldmm = current->mm;
    if (!oldmm)
        return 0;

    //Initialization of vmacache entry

    // CLONE_If a VM is configured, the calling process and child processes
    //It runs in the same memory space.
    if (clone_flags & CLONE_VM) {
        //Set mm of parent process to child and good_To mm
        mm = oldmm;
        goto good_mm;

    retval = -ENOMEM;
    // CLONE_Duplicate the existing mm structure if the VM is not set
    mm = dup_mm(tsk, current->mm);
    if (!mm)
        goto fail_nomem;

    tsk->mm = mm;
    tsk->active_mm = mm;
    return 0;

    return retval;

The process of copy_mm called after clone (2). It turns out that if CLONE_VM is set (flag at thread creation) it shares an address with the parent process.

static struct mm_struct *dup_mm(struct task_struct *tsk,
                struct mm_struct *oldmm)
    struct mm_struct *mm;
    int err;

    mm = allocate_mm();
    if (!mm)
        goto fail_nomem;

    //Copy the memory of the parent process to the generated process
    memcpy(mm, oldmm, sizeof(*mm));

    if (!mm_init(mm, tsk, mm->user_ns))
        goto fail_nomem;

    err = dup_mmap(mm, oldmm);
    if (err)
        goto free_pt;

    mm->hiwater_rss = get_mm_rss(mm);
    mm->hiwater_vm = mm->total_vm;

    if (mm->binfmt && !try_module_get(mm->binfmt->module))
        goto free_pt;

    return mm;

    /* don't put binfmt in mmput, we haven't got module yet */
    mm->binfmt = NULL;
    mm_init_owner(mm, NULL);

    return NULL;

The main processing of copy_mm. If CLONE_VM (thread) is set at the time of the previous process, this process is not performed. Threads can access the data from which the thread was created. In the case of a process, the process of copying the memory of the parent process is performed. (To be described later.)


mm_struct --Structure that manages address space information

item Overview
mmap vm_area_Hold the beginning of the struct
mm_rb Red for fast search of memory area-Hold a black tree
mmap_cache Locality of reference for memory(locality)To speed up by taking advantage of
mm_count Reference counter for this structure. If 0, no object is pointed to
mm_list mm_struct Field for making a list of structs
start_code, end_code Start and end addresses of the text segment
start_brk, brk Heap start and end addresses
start_stack Start address of the stack


Recommended Posts

Linux --Look around copy_mm ()
Play around with Linux partitions ~ Continued ~