From 5d5702a3ec24cd1bc7effbadb13d272fa51dff05 Mon Sep 17 00:00:00 2001 From: Niu Yawei Date: Mon, 10 Jul 2017 22:26:12 -0400 Subject: [PATCH] LU-9725 lwp: wait on deregister When lustre_deregister_lwp_item() is being called, it should wait for the inflight callback done before moving on to free the data used by the callback. Signed-off-by: Niu Yawei Change-Id: I9c27a0ae4c765147fd183b78bf3693a66e7511dc Reviewed-on: https://review.whamcloud.com/27987 Tested-by: Jenkins Reviewed-by: Fan Yong Tested-by: Maloo Reviewed-by: Lai Siyao Reviewed-by: Oleg Drokin --- lustre/obdclass/obd_mount_server.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/lustre/obdclass/obd_mount_server.c b/lustre/obdclass/obd_mount_server.c index afd51ac..839c7a2 100644 --- a/lustre/obdclass/obd_mount_server.c +++ b/lustre/obdclass/obd_mount_server.c @@ -455,18 +455,34 @@ EXPORT_SYMBOL(lustre_register_lwp_item); void lustre_deregister_lwp_item(struct obd_export **exp) { struct lwp_register_item *lri; + bool removed = false; + int repeat = 0; spin_lock(&lwp_register_list_lock); list_for_each_entry(lri, &lwp_register_list, lri_list) { if (exp == lri->lri_exp) { list_del_init(&lri->lri_list); - spin_unlock(&lwp_register_list_lock); - - lustre_put_lwp_item(lri); - return; + removed = true; + break; } } spin_unlock(&lwp_register_list_lock); + + if (!removed) + return; + + /* See lustre_notify_lwp_list(), in some extreme race conditions, + * the notify callback could be still on the fly, we need to wait + * for the callback done before moving on to free the data used + * by callback. */ + while (atomic_read(&lri->lri_ref) > 1) { + CDEBUG(D_MOUNT, "lri reference count %u, repeat: %d\n", + atomic_read(&lri->lri_ref), repeat); + repeat++; + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(cfs_time_seconds(1)); + } + lustre_put_lwp_item(lri); } EXPORT_SYMBOL(lustre_deregister_lwp_item); -- 1.8.3.1