diff options
Diffstat (limited to 'drivers/infiniband/hw/hfi1/mmu_rb.c')
-rw-r--r-- | drivers/infiniband/hw/hfi1/mmu_rb.c | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/drivers/infiniband/hw/hfi1/mmu_rb.c b/drivers/infiniband/hw/hfi1/mmu_rb.c index 1c7e25b90a2c..e5c5ef4cf06c 100644 --- a/drivers/infiniband/hw/hfi1/mmu_rb.c +++ b/drivers/infiniband/hw/hfi1/mmu_rb.c @@ -58,6 +58,7 @@ struct mmu_rb_handler { struct rb_root *root; spinlock_t lock; /* protect the RB tree */ struct mmu_rb_ops *ops; + struct mm_struct *mm; }; static LIST_HEAD(mmu_rb_handlers); @@ -95,9 +96,11 @@ static unsigned long mmu_node_last(struct mmu_rb_node *node) return PAGE_ALIGN(node->addr + node->len) - 1; } -int hfi1_mmu_rb_register(struct rb_root *root, struct mmu_rb_ops *ops) +int hfi1_mmu_rb_register(struct mm_struct *mm, struct rb_root *root, + struct mmu_rb_ops *ops) { struct mmu_rb_handler *handlr; + int ret; handlr = kmalloc(sizeof(*handlr), GFP_KERNEL); if (!handlr) @@ -108,11 +111,19 @@ int hfi1_mmu_rb_register(struct rb_root *root, struct mmu_rb_ops *ops) INIT_HLIST_NODE(&handlr->mn.hlist); spin_lock_init(&handlr->lock); handlr->mn.ops = &mn_opts; + handlr->mm = mm; + + ret = mmu_notifier_register(&handlr->mn, handlr->mm); + if (ret) { + kfree(handlr); + return ret; + } + spin_lock(&mmu_rb_lock); list_add_tail_rcu(&handlr->list, &mmu_rb_handlers); spin_unlock(&mmu_rb_lock); - return mmu_notifier_register(&handlr->mn, current->mm); + return ret; } void hfi1_mmu_rb_unregister(struct rb_root *root) @@ -126,8 +137,7 @@ void hfi1_mmu_rb_unregister(struct rb_root *root) return; /* Unregister first so we don't get any more notifications. */ - if (current->mm) - mmu_notifier_unregister(&handler->mn, current->mm); + mmu_notifier_unregister(&handler->mn, handler->mm); spin_lock(&mmu_rb_lock); list_del_rcu(&handler->list); |