Index: linux-2.6/include/linux/mmu_notifier.h =================================================================== --- linux-2.6.orig/include/linux/mmu_notifier.h 2008-01-24 13:48:48.000000000 -0800 +++ linux-2.6/include/linux/mmu_notifier.h 2008-01-24 14:05:04.000000000 -0800 @@ -3,6 +3,7 @@ #include #include +#include #ifdef CONFIG_MMU_NOTIFIER @@ -24,7 +25,6 @@ struct mmu_notifier_ops { struct mmu_notifier_head { struct hlist_head head; - rwlock_t lock; }; struct mmu_notifier { @@ -45,7 +45,6 @@ extern int mmu_notifier_age_page(struct static inline void mmu_notifier_head_init(struct mmu_notifier_head *mnh) { INIT_HLIST_HEAD(&mnh->head); - rwlock_init(&mnh->lock); } #define mmu_notifier(function, mm, args...) \ @@ -54,15 +53,15 @@ static inline void mmu_notifier_head_ini struct hlist_node *__n; \ \ if (unlikely(!hlist_empty(&(mm)->mmu_notifier.head))) { \ - read_lock(&(mm)->mmu_notifier.lock); \ - hlist_for_each_entry(__mn, __n, \ + rcu_read_lock(); \ + hlist_for_each_entry_rcu(__mn, __n, \ &(mm)->mmu_notifier.head, \ hlist) \ if (__mn->ops->function) \ __mn->ops->function(__mn, \ mm, \ args); \ - read_unlock(&(mm)->mmu_notifier.lock); \ + rcu_read_unlock(); \ } \ } while (0) Index: linux-2.6/mm/mmu_notifier.c =================================================================== --- linux-2.6.orig/mm/mmu_notifier.c 2008-01-24 13:47:20.000000000 -0800 +++ linux-2.6/mm/mmu_notifier.c 2008-01-24 14:16:49.000000000 -0800 @@ -13,17 +13,17 @@ void mmu_notifier_release(struct mm_struct *mm) { struct mmu_notifier *mn; - struct hlist_node *n, *tmp; + struct hlist_node *n; if (unlikely(!hlist_empty(&mm->mmu_notifier.head))) { - read_lock(&mm->mmu_notifier.lock); - hlist_for_each_entry_safe(mn, n, tmp, + rcu_read_lock(); + hlist_for_each_entry_rcu(mn, n, &mm->mmu_notifier.head, hlist) { if (mn->ops->release) mn->ops->release(mn, mm); hlist_del(&mn->hlist); } - read_unlock(&mm->mmu_notifier.lock); + rcu_read_unlock(); } } @@ -35,17 +35,17 @@ void mmu_notifier_release(struct mm_stru int mmu_notifier_age_page(struct mm_struct *mm, unsigned long address) { struct mmu_notifier *mn; - struct hlist_node *n, *tmp; + struct hlist_node *n; int young = 0; if (unlikely(!hlist_empty(&mm->mmu_notifier.head))) { - read_lock(&mm->mmu_notifier.lock); - hlist_for_each_entry_safe(mn, n, tmp, + rcu_read_lock(); + hlist_for_each_entry_rcu(mn, n, &mm->mmu_notifier.head, hlist) { if (mn->ops->age_page) young |= mn->ops->age_page(mn, mm, address); } - read_unlock(&mm->mmu_notifier.lock); + rcu_read_unlock(); } return young; @@ -53,16 +53,12 @@ int mmu_notifier_age_page(struct mm_stru void mmu_notifier_register(struct mmu_notifier *mn, struct mm_struct *mm) { - write_lock(&mm->mmu_notifier.lock); hlist_add_head(&mn->hlist, &mm->mmu_notifier.head); - write_unlock(&mm->mmu_notifier.lock); } EXPORT_SYMBOL_GPL(mmu_notifier_register); void mmu_notifier_unregister(struct mmu_notifier *mn, struct mm_struct *mm) { - write_lock(&mm->mmu_notifier.lock); hlist_del(&mn->hlist); - write_unlock(&mm->mmu_notifier.lock); } EXPORT_SYMBOL_GPL(mmu_notifier_unregister);