From c9f1267ff3efcc7c56e4468447280b1ba637e65e Mon Sep 17 00:00:00 2001 From: panda Date: Tue, 8 Dec 2009 21:28:04 +0000 Subject: [PATCH] b=21348 i=Mike Pershin i=Alexander Zarochentsev adding proper maintainance of the evictor list --- lustre/include/obd.h | 1 + lustre/obdclass/obd_config.c | 1 + lustre/ptlrpc/pinger.c | 32 ++++++++++++++++++-------------- 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/lustre/include/obd.h b/lustre/include/obd.h index 0da24e2..45a0aa1 100644 --- a/lustre/include/obd.h +++ b/lustre/include/obd.h @@ -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. diff --git a/lustre/obdclass/obd_config.c b/lustre/obdclass/obd_config.c index f573ade..ae04e35 100644 --- a/lustre/obdclass/obd_config.c +++ b/lustre/obdclass/obd_config.c @@ -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); diff --git a/lustre/ptlrpc/pinger.c b/lustre/ptlrpc/pinger.c index f36e3e1..391ddcb 100644 --- a/lustre/ptlrpc/pinger.c +++ b/lustre/ptlrpc/pinger.c @@ -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"); -- 1.8.3.1