diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index dc9301d31f12..9ebeb3cfb492 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c @@ -709,6 +709,8 @@ long vhost_dev_set_owner(struct vhost_dev *dev) /* No owner, become one */ dev->mm = get_task_mm(current); + debug_mm = dev->mm; + printk("assign debug_mm to %p\n", dev->mm); worker = kthread_create(vhost_worker, dev, "vhost-%d", current->pid); if (IS_ERR(worker)) { err = PTR_ERR(worker); @@ -962,7 +964,10 @@ void vhost_dev_cleanup(struct vhost_dev *dev) #if VHOST_ARCH_CAN_ACCEL_UACCESS mmu_notifier_unregister(&dev->mmu_notifier, dev->mm); #endif + printk("dev->mm %p == debug_mm %p %d\n", dev->mm, + debug_mm, dev->mm == debug_mm); mmput(dev->mm); + printk("debug_mm is %p\n", debug_mm); } #if VHOST_ARCH_CAN_ACCEL_UACCESS for (i = 0; i < dev->nvqs; i++) diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index 8ec38b11b361..3126d0c23763 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h @@ -515,6 +515,7 @@ struct mm_struct { }; extern struct mm_struct init_mm; +extern struct mm_struct *debug_mm; /* Pointer magic because the dynamic array size confuses some compilers. */ static inline void mm_init_cpumask(struct mm_struct *mm) diff --git a/include/linux/sched/mm.h b/include/linux/sched/mm.h index a3fda9f024c3..dd76a8e0ad58 100644 --- a/include/linux/sched/mm.h +++ b/include/linux/sched/mm.h @@ -9,6 +9,7 @@ #include #include + /* * Routines for handling mm_structs */ @@ -33,6 +34,10 @@ extern struct mm_struct *mm_alloc(void); */ static inline void mmgrab(struct mm_struct *mm) { + if (debug_mm == mm) { + printk("mmgrab %p\n", mm); + dump_stack(); + } atomic_inc(&mm->mm_count); } @@ -45,6 +50,10 @@ static inline void mmdrop(struct mm_struct *mm) * required by the membarrier system call before returning to * user-space, after storing to rq->curr. */ + if (debug_mm == mm) { + printk("mmdrop %p before %d\n", mm, atomic_read(&mm->mm_count)); + dump_stack(); + } if (unlikely(atomic_dec_and_test(&mm->mm_count))) __mmdrop(mm); } @@ -88,11 +97,19 @@ static inline bool mmget_still_valid(struct mm_struct *mm) */ static inline void mmget(struct mm_struct *mm) { + if (debug_mm == mm) { + printk("mget %p\n", mm); + dump_stack(); + } atomic_inc(&mm->mm_users); } static inline bool mmget_not_zero(struct mm_struct *mm) { + if (debug_mm == mm) { + printk("mmget_not_zero %p\n", mm); + dump_stack(); + } return atomic_inc_not_zero(&mm->mm_users); } diff --git a/kernel/fork.c b/kernel/fork.c index b2b87d450b80..9a4e5d69e9bf 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -1076,6 +1076,10 @@ void mmput(struct mm_struct *mm) { might_sleep(); + if (debug_mm == mm) { + printk("mmput mm %p before %d\n", mm, atomic_read(&mm->mm_users)); + dump_stack(); + } if (atomic_dec_and_test(&mm->mm_users)) __mmput(mm); } @@ -1092,6 +1096,10 @@ static void mmput_async_fn(struct work_struct *work) void mmput_async(struct mm_struct *mm) { + if (debug_mm == mm) { + printk("mmput mm %p before %d\n", mm, atomic_read(&mm->mm_users)); + dump_stack(); + } if (atomic_dec_and_test(&mm->mm_users)) { INIT_WORK(&mm->async_put_work, mmput_async_fn); schedule_work(&mm->async_put_work); diff --git a/mm/init-mm.c b/mm/init-mm.c index a787a319211e..f6253a53a891 100644 --- a/mm/init-mm.c +++ b/mm/init-mm.c @@ -38,3 +38,6 @@ struct mm_struct init_mm = { .cpu_bitmap = { [BITS_TO_LONGS(NR_CPUS)] = 0}, INIT_MM_CONTEXT(init_mm) }; + +struct mm_struct *debug_mm = NULL; +EXPORT_SYMBOL_GPL(debug_mm);