Whamcloud - gitweb
LU-9725 lwp: wait on deregister 61/28161/2
authorNiu Yawei <yawei.niu@intel.com>
Thu, 20 Jul 2017 23:46:25 +0000 (16:46 -0700)
committerOleg Drokin <oleg.drokin@intel.com>
Fri, 21 Jul 2017 17:06:11 +0000 (17:06 +0000)
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.

This patch is back-ported from the following one:
Lustre-commit: 5d5702a3ec24cd1bc7effbadb13d272fa51dff05
Lustre-change: https://review.whamcloud.com/27987

Signed-off-by: Niu Yawei <yawei.niu@intel.com>
Change-Id: I9c27a0ae4c765147fd183b78bf3693a66e7511dc
Reviewed-by: Fan Yong <fan.yong@intel.com>
Reviewed-by: Lai Siyao <lai.siyao@intel.com>
Reviewed-on: https://review.whamcloud.com/28161
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
lustre/obdclass/obd_mount_server.c

index afd51ac..839c7a2 100644 (file)
@@ -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);