X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Fptlrpc%2Fpinger.c;h=866e7eb649260a13a50ab42bb21242fda1f59c80;hp=01d7d236cb443ab8fbb6471dafdfdcb1388b34ad;hb=8c9a3b75ac27ee0b04593ac5424a0b74d176ccd1;hpb=090c677210ee2946d99c71412e4ff762bb300f4f diff --git a/lustre/ptlrpc/pinger.c b/lustre/ptlrpc/pinger.c index 01d7d23..866e7eb 100644 --- a/lustre/ptlrpc/pinger.c +++ b/lustre/ptlrpc/pinger.c @@ -35,31 +35,30 @@ #include #include "ptlrpc_internal.h" +#define PINGER_RATE 3 /* how many pings we'll do in obd_timeout period */ + static DECLARE_MUTEX(pinger_sem); static struct list_head pinger_imports = LIST_HEAD_INIT(pinger_imports); -static struct ptlrpc_thread *pinger_thread = NULL; - int ptlrpc_ping(struct obd_import *imp) { struct ptlrpc_request *req; int rc = 0; ENTRY; - req = ptlrpc_prep_req(imp, OBD_PING, 0, NULL, - NULL); + req = ptlrpc_prep_req(imp, LUSTRE_OBD_VERSION, OBD_PING, 0, NULL, NULL); if (req) { DEBUG_REQ(D_HA, req, "pinging %s->%s", imp->imp_obd->obd_uuid.uuid, imp->imp_target_uuid.uuid); req->rq_no_resend = req->rq_no_delay = 1; - req->rq_replen = lustre_msg_size(0, - NULL); + req->rq_replen = lustre_msg_size(0, NULL); + req->rq_timeout = obd_timeout / PINGER_RATE; ptlrpcd_add_req(req); } else { CERROR("OOM trying to ping %s->%s\n", - imp->imp_obd->obd_uuid.uuid, - imp->imp_target_uuid.uuid); + imp->imp_obd->obd_uuid.uuid, + imp->imp_target_uuid.uuid); rc = -ENOMEM; } @@ -67,6 +66,97 @@ int ptlrpc_ping(struct obd_import *imp) } #ifdef __KERNEL__ +static inline int ptlrpc_next_ping(struct obd_import *imp) +{ + return jiffies + (obd_timeout / PINGER_RATE * HZ); +} + +static inline int ptlrpc_next_reconnect(struct obd_import *imp) +{ + if (imp->imp_server_timeout) + return jiffies + (obd_timeout / 2 * HZ); + else + return jiffies + (obd_timeout * HZ); +} + +static atomic_t suspend_timeouts = ATOMIC_INIT(0); +static wait_queue_head_t suspend_timeouts_waitq; + +void ptlrpc_deactivate_timeouts(void) +{ + CDEBUG(D_HA, "deactivate timeouts\n"); + atomic_inc(&suspend_timeouts); +} + +void ptlrpc_activate_timeouts(void) +{ + CDEBUG(D_HA, "activate timeouts\n"); + LASSERT(atomic_read(&suspend_timeouts) > 0); + if (atomic_dec_and_test(&suspend_timeouts)) + wake_up(&suspend_timeouts_waitq); +} + +int ptlrpc_check_suspend(void) +{ + if (atomic_read(&suspend_timeouts)) + return 1; + return 0; +} + +int ptlrpc_check_and_wait_suspend(struct ptlrpc_request *req) +{ + struct l_wait_info lwi; + + if (atomic_read(&suspend_timeouts)) { + DEBUG_REQ(D_NET, req, "-- suspend %d regular timeout", + atomic_read(&suspend_timeouts)); + lwi = LWI_INTR(NULL, NULL); + l_wait_event(suspend_timeouts_waitq, + atomic_read(&suspend_timeouts) == 0, &lwi); + DEBUG_REQ(D_NET, req, "-- recharge regular timeout"); + return 1; + } + return 0; +} + +static void ptlrpc_pinger_process_import(struct obd_import *imp, + unsigned long this_ping) +{ + unsigned long flags; + int force, level; + + spin_lock_irqsave(&imp->imp_lock, flags); + level = imp->imp_state; + force = imp->imp_force_verify; + if (force) + imp->imp_force_verify = 0; + spin_unlock_irqrestore(&imp->imp_lock, flags); + + if ((imp->imp_next_ping - this_ping > 0) && + (imp->imp_next_ping - this_ping > obd_timeout * HZ)) { + CWARN("wrong ping time %lu (current %lu)\n", + imp->imp_next_ping, this_ping); + imp->imp_next_ping = ptlrpc_next_reconnect(imp); + } + + if (imp->imp_next_ping > this_ping && force == 0) + return; + + if (level == LUSTRE_IMP_DISCON && !imp->imp_deactive) { + /* wait at least a timeout before trying recovery again */ + imp->imp_next_ping = ptlrpc_next_reconnect(imp); + ptlrpc_initiate_recovery(imp); + } else if (level != LUSTRE_IMP_FULL || imp->imp_obd->obd_no_recov) { + CDEBUG(D_HA, "not pinging %s (in recovery " + " or recovery disabled: %s)\n", + imp->imp_target_uuid.uuid, + ptlrpc_import_state_name(level)); + } else if (imp->imp_pingable || force) { + imp->imp_next_ping = ptlrpc_next_ping(imp); + ptlrpc_ping(imp); + } +} + static int ptlrpc_pinger_main(void *arg) { struct ptlrpc_svc_data *data = (struct ptlrpc_svc_data *)arg; @@ -82,7 +172,10 @@ static int ptlrpc_pinger_main(void *arg) RECALC_SIGPENDING; SIGNAL_MASK_UNLOCK(current, flags); - THREAD_NAME(current->comm, "%s", data->name); + LASSERTF(strlen(data->name) < sizeof(current->comm), + "name %d > len %d\n", + (int)strlen(data->name), (int)sizeof(current->comm)); + THREAD_NAME(current->comm, sizeof(current->comm) - 1, "%s", data->name); unlock_kernel(); /* Record that the thread is running */ @@ -97,54 +190,27 @@ static int ptlrpc_pinger_main(void *arg) NULL, NULL); struct list_head *iter; + time_to_next_ping = this_ping + (obd_timeout * HZ) - jiffies; down(&pinger_sem); list_for_each(iter, &pinger_imports) { struct obd_import *imp = list_entry(iter, struct obd_import, imp_pinger_chain); - int force, level; - unsigned long flags; - - - spin_lock_irqsave(&imp->imp_lock, flags); - level = imp->imp_state; - force = imp->imp_force_verify; - if (force) - imp->imp_force_verify = 0; - spin_unlock_irqrestore(&imp->imp_lock, flags); - - if (imp->imp_next_ping <= this_ping || force) { - if (level == LUSTRE_IMP_DISCON) { - /* wait at least a timeout before - trying recovery again. */ - imp->imp_next_ping = jiffies + - (obd_timeout * HZ); - ptlrpc_initiate_recovery(imp); - } - else if (level != LUSTRE_IMP_FULL || - imp->imp_obd->obd_no_recov) { - CDEBUG(D_HA, - "not pinging %s (in recovery " - " or recovery disabled: %s)\n", - imp->imp_target_uuid.uuid, - ptlrpc_import_state_name(level)); - } - else if (imp->imp_pingable || force) { - ptlrpc_ping(imp); - } - - } else { - if (imp->imp_pingable) - CDEBUG(D_HA, "don't need to ping %s " - "(%lu > %lu)\n", - imp->imp_target_uuid.uuid, - imp->imp_next_ping, this_ping); - } + + ptlrpc_pinger_process_import(imp, this_ping); + + CDEBUG(D_OTHER, "%s: pingable %d, next_ping %lu(%lu)\n", + imp->imp_target_uuid.uuid, + imp->imp_pingable, imp->imp_next_ping, jiffies); + + if (imp->imp_pingable && imp->imp_next_ping && + imp->imp_next_ping - jiffies < time_to_next_ping && + imp->imp_next_ping > jiffies) + time_to_next_ping = imp->imp_next_ping - jiffies; } up(&pinger_sem); /* Wait until the next ping time, or until we're stopped. */ - time_to_next_ping = this_ping + (obd_timeout * HZ) - jiffies; CDEBUG(D_HA, "next ping in %lu (%lu)\n", time_to_next_ping, this_ping + (obd_timeout * HZ)); if (time_to_next_ping > 0) { @@ -170,6 +236,8 @@ static int ptlrpc_pinger_main(void *arg) return 0; } +static struct ptlrpc_thread *pinger_thread = NULL; + int ptlrpc_start_pinger(void) { struct l_wait_info lwi = { 0 }; @@ -180,6 +248,8 @@ int ptlrpc_start_pinger(void) #endif ENTRY; + LASSERT(obd_timeout > PINGER_RATE); + if (pinger_thread != NULL) RETURN(-EALREADY); @@ -187,6 +257,7 @@ int ptlrpc_start_pinger(void) if (pinger_thread == NULL) RETURN(-ENOMEM); init_waitqueue_head(&pinger_thread->t_ctl_waitq); + init_waitqueue_head(&suspend_timeouts_waitq); d.name = "ll_ping"; d.thread = pinger_thread; @@ -232,7 +303,7 @@ int ptlrpc_stop_pinger(void) void ptlrpc_pinger_sending_on_import(struct obd_import *imp) { down(&pinger_sem); - imp->imp_next_ping = jiffies + (obd_timeout * HZ); + imp->imp_next_ping = ptlrpc_next_ping(imp); up(&pinger_sem); } @@ -337,8 +408,11 @@ static int pinger_check_rpcs(void *arg) if (level == LUSTRE_IMP_DISCON) { /* wait at least a timeout before trying recovery again. */ + unsigned long timeout = obd_timeout; + if (imp->imp_server_timeout) + timeout = obd_timeout / 2; imp->imp_next_ping = time(NULL) + - (obd_timeout * HZ); + (timeout * HZ); ptlrpc_initiate_recovery(imp); } else if (level != LUSTRE_IMP_FULL ||