Whamcloud - gitweb
b=21348
authorpanda <panda>
Tue, 8 Dec 2009 21:28:04 +0000 (21:28 +0000)
committerpanda <panda>
Tue, 8 Dec 2009 21:28:04 +0000 (21:28 +0000)
i=Mike Pershin
i=Alexander Zarochentsev

adding proper maintainance of the evictor list

lustre/include/obd.h
lustre/obdclass/obd_config.c
lustre/ptlrpc/pinger.c

index 0da24e2..45a0aa1 100644 (file)
@@ -1129,6 +1129,7 @@ struct obd_device {
         struct lprocfs_stats  *obd_svc_stats;
         atomic_t               obd_evict_inprogress;
         cfs_waitq_t            obd_evict_inprogress_waitq;
+        struct list_head       obd_evict_list; /* protected with pet_lock */
 
         /**
          * Ldlm pool part. Save last calculated SLV and Limit.
index f573ade..ae04e35 100644 (file)
@@ -276,6 +276,7 @@ int class_attach(struct lustre_cfg *lcfg)
         CFS_INIT_LIST_HEAD(&obd->obd_req_replay_queue);
         CFS_INIT_LIST_HEAD(&obd->obd_lock_replay_queue);
         CFS_INIT_LIST_HEAD(&obd->obd_final_req_queue);
+        CFS_INIT_LIST_HEAD(&obd->obd_evict_list);
 
         llog_group_init(&obd->obd_olg, FILTER_GROUP_LLOG);
 
index f36e3e1..391ddcb 100644 (file)
@@ -576,23 +576,25 @@ void ptlrpc_pinger_wake_up()
 static int               pet_refcount = 0;
 static int               pet_state;
 static wait_queue_head_t pet_waitq;
-static struct obd_export *pet_exp = NULL;
+CFS_LIST_HEAD(pet_list);
 static spinlock_t        pet_lock = SPIN_LOCK_UNLOCKED;
 
 int ping_evictor_wake(struct obd_export *exp)
 {
+        struct obd_device *obd;
+
         spin_lock(&pet_lock);
-        if (pet_exp || (pet_state != PET_READY)) {
+        if (pet_state != PET_READY) {
                 /* eventually the new obd will call here again. */
                 spin_unlock(&pet_lock);
                 return 1;
         }
 
-        /* We have to make sure the obd isn't destroyed between now and when
-         * the ping evictor runs.  We'll take a reference here, and drop it
-         * when we finish in the evictor.  We don't really care about this
-         * export in particular; we just need one to keep the obd alive. */
-        pet_exp = class_export_get(exp);
+        obd = class_exp2obd(exp);
+        if (list_empty(&obd->obd_evict_list)) {
+                class_incref(obd, __FUNCTION__, cfs_current());
+                list_add(&obd->obd_evict_list, &pet_list);
+        }
         spin_unlock(&pet_lock);
 
         wake_up(&pet_waitq);
@@ -610,19 +612,21 @@ static int ping_evictor_main(void *arg)
         cfs_daemonize_ctxt("ll_evictor");
 
         CDEBUG(D_HA, "Starting Ping Evictor\n");
-        pet_exp = NULL;
         pet_state = PET_READY;
         while (1) {
-                l_wait_event(pet_waitq, pet_exp ||
+                l_wait_event(pet_waitq, (!list_empty(&pet_list)) ||
                              (pet_state == PET_TERMINATE), &lwi);
-                if (pet_state == PET_TERMINATE)
+
+                /* loop until all obd's will be removed */
+                if ((pet_state == PET_TERMINATE) && list_empty(&pet_list))
                         break;
 
                 /* we only get here if pet_exp != NULL, and the end of this
                  * loop is the only place which sets it NULL again, so lock
                  * is not strictly necessary. */
                 spin_lock(&pet_lock);
-                obd = pet_exp->exp_obd;
+                obd = list_entry(pet_list.next, struct obd_device,
+                                 obd_evict_list);
                 spin_unlock(&pet_lock);
 
                 expire_time = cfs_time_current_sec() - PING_EVICT_TIMEOUT;
@@ -666,11 +670,11 @@ static int ping_evictor_main(void *arg)
                 }
                 spin_unlock(&obd->obd_dev_lock);
 
-                class_export_put(pet_exp);
-
                 spin_lock(&pet_lock);
-                pet_exp = NULL;
+                list_del_init(&obd->obd_evict_list);
                 spin_unlock(&pet_lock);
+
+                class_decref(obd, __FUNCTION__, cfs_current());
         }
         CDEBUG(D_HA, "Exiting Ping Evictor\n");