diff -NurpP --minimal linux-2.6.10-vs1.9.3.14.6/include/linux/list.h linux-2.6.10-vs1.9.3.14.6.x/include/linux/list.h --- linux-2.6.10-vs1.9.3.14.6/include/linux/list.h Wed Dec 29 19:14:28 2004 +++ linux-2.6.10-vs1.9.3.14.6.x/include/linux/list.h Thu Dec 30 20:28:45 2004 @@ -642,6 +642,10 @@ static inline void hlist_add_after(struc for ((pos) = (head)->first; pos && ({ prefetch((pos)->next); 1; }); \ (pos) = rcu_dereference((pos)->next)) +#define hlist_for_each_safe_rcu(pos, n, head) \ + for ((pos) = (head)->first; pos && ({ n = (pos)->next; 1; }); \ + (pos) = rcu_dereference(n)) + /** * hlist_for_each_entry - iterate over list of given type * @tpos: the type * to use as a loop counter. @@ -708,6 +712,25 @@ static inline void hlist_add_after(struc pos && ({ prefetch(pos->next); 1;}) && \ ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ pos = rcu_dereference(pos->next)) + +/** + * hlist_for_each_entry_safe_rcu - iterate over list safe against removal + * @tpos: the type * to use as a loop counter. + * @pos: the &struct hlist_node to use as a loop counter. + * @n: another &struct hlist_node to use as temporary storage + * @head: the head for your list. + * @member: the name of the hlist_node within the struct. + * + * This list-traversal primitive may safely run concurrently with + * the _rcu list-mutation primitives such as hlist_add_rcu() + * as long as the traversal is guarded by rcu_read_lock(). + */ +#define hlist_for_each_entry_safe_rcu(tpos, pos, n, head, member) \ + for (pos = (head)->first; \ + pos && ({ n = pos->next; 1; }) && \ + ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ + pos = rcu_dereference(n)) + #else #warning "don't include kernel headers in userspace" diff -NurpP --minimal linux-2.6.10-vs1.9.3.14.6/kernel/fork.c linux-2.6.10-vs1.9.3.14.6.x/kernel/fork.c --- linux-2.6.10-vs1.9.3.14.6/kernel/fork.c Sun Jan 2 02:57:09 2005 +++ linux-2.6.10-vs1.9.3.14.6.x/kernel/fork.c Thu Dec 30 03:30:03 2004 @@ -304,10 +304,10 @@ static struct mm_struct * mm_init(struct mm->ioctx_list = NULL; mm->default_kioctx = (struct kioctx)INIT_KIOCTX(mm->default_kioctx, *mm); mm->free_area_cache = TASK_UNMAPPED_BASE; - mm->mm_vx_info = NULL; if (likely(!mm_alloc_pgd(mm))) { mm->def_flags = 0; + set_vx_info(&mm->mm_vx_info, current->vx_info); return mm; } free_mm(mm); @@ -325,7 +325,6 @@ struct mm_struct * mm_alloc(void) if (mm) { memset(mm, 0, sizeof(*mm)); mm = mm_init(mm); - set_vx_info(&mm->mm_vx_info, current->vx_info); } return mm; } @@ -467,14 +466,13 @@ static int copy_mm(unsigned long clone_f /* Copy the current MM stuff.. */ memcpy(mm, oldmm, sizeof(*mm)); + mm->mm_vx_info = NULL; if (!mm_init(mm)) goto fail_nomem; if (init_new_context(tsk,mm)) goto fail_nocontext; - // set_vx_info(&mm->mm_vx_info, oldmm->mm_vx_info); - set_vx_info(&mm->mm_vx_info, current->vx_info); retval = dup_mmap(mm, oldmm); if (retval) goto free_pt;