Whamcloud - gitweb
b=21574 more pinger fixes
authorJohann Lombardi <johann@sun.com>
Sat, 16 Jan 2010 14:39:22 +0000 (15:39 +0100)
committerJohann Lombardi <johann@sun.com>
Sat, 16 Jan 2010 14:39:22 +0000 (15:39 +0100)
i=oleg
i=andrew

- ptlrpc_update_next_ping(): don't postpone next ping when "soon"
  is set and a ping request is already scheduled before the new
  deadline.
- It is usually fine to extend the deadline for the next ping
  since we are granted that the pinger will wake up before
  this new deadline and update his timer.
  However, the purpose of ptlrpc_pinger_commit_expected() is to
  schedule ping earlier. To support this, i've changed
  ptlrpc_update_next_ping() to wake up the pinger if the new
  ping deadline is before the pinger is supposed to wake up.

lustre/ChangeLog
lustre/ptlrpc/pinger.c
lustre/ptlrpc/ptlrpc_module.c

index bb5aa7a..e3b0178 100644 (file)
@@ -355,6 +355,11 @@ Bugzilla   : 20065
 Description: Parallel statfs() calls result in client eviction
 Details    : cache statfs data for 1s.
 
+Bugzilla   : 21574
+Description: parallel-scale test_compilebench: @@@@@@ FAIL: compilebench
+            failed: 1
+Details    : fix serveral issues in pinger code causing clients not to ping
+            servers for too long, resulting in evictions.
 
 -------------------------------------------------------------------------------
 
index 0f3bd3b..130621f 100644 (file)
 #include <lustre_net.h>
 #include "ptlrpc_internal.h"
 
+#ifdef __KERNEL__
+/* What time pinger is supposed to wake up next.
+ * pd_next_ping is the equivalent for liblustre. */
+cfs_time_t pinger_next_wake;
+#endif
+
 struct semaphore pinger_sem;
 static struct list_head pinger_imports = CFS_LIST_HEAD_INIT(pinger_imports);
 static struct list_head timeout_list = CFS_LIST_HEAD_INIT(timeout_list);
@@ -145,8 +151,26 @@ static void ptlrpc_update_next_ping(struct obd_import *imp, int soon)
                                          PING_INTERVAL);
                 dtime = delay - (ctime % delay);
         }
+
+        dtime = cfs_time_add(ctime, dtime);
+
+        if (soon && cfs_time_after(imp->imp_next_ping, ctime) &&
+            cfs_time_after(dtime, imp->imp_next_ping)) {
+                /* if the next ping is due to be sent before the
+                 * new deadline, don't delay it */
+                 return;
+        }
+
         /* May harmlessly race with ptlrpc_update_next_ping() */
-        imp->imp_next_ping = cfs_time_add(ctime, dtime);
+        imp->imp_next_ping = dtime;
+
+#ifdef __KERNEL__
+        if (pinger_next_wake != 0 && cfs_time_after(pinger_next_wake, dtime))
+                /* pinger is supposed to sleep until after the new ping
+                 * deadline, wake it up to take into account our update.
+                 * no needed for liblustre which updates pd_next_ping. */
+                ptlrpc_pinger_wake_up();
+#endif
 
         CDEBUG(D_INFO, "Setting %s next ping to "CFS_TIME_T" ("CFS_TIME_T")\n",
                obd2cli_tgt(imp->imp_obd), imp->imp_next_ping, dtime);
@@ -206,7 +230,6 @@ static int ptlrpc_pinger_main(void *arg)
                 struct timeout_item *item;
                 struct list_head *iter;
 
-                time_to_next_wake = cfs_time_seconds(PING_INTERVAL);
                 time_of_next_wake = cfs_time_shift(PING_INTERVAL);
 
                 mutex_down(&pinger_sem);
@@ -272,16 +295,17 @@ static int ptlrpc_pinger_main(void *arg)
 
                         /* Wait time until next ping, or until we stopped. */
                         if (cfs_time_before(imp->imp_next_ping,
-                                            time_of_next_wake)) {
+                                            time_of_next_wake))
                                 time_of_next_wake = imp->imp_next_ping;
-                                time_to_next_wake = max_t(cfs_duration_t,
-                                        cfs_time_seconds(1),
-                                        cfs_time_sub(time_of_next_wake,
-                                                     cfs_time_current()));
-                        }
                 }
+                pinger_next_wake = time_of_next_wake;
                 mutex_up(&pinger_sem);
                 obd_update_maxusage();
+
+                time_to_next_wake = max_t(cfs_duration_t,
+                                          cfs_time_seconds(1),
+                                          cfs_time_sub(time_of_next_wake,
+                                                       cfs_time_current()));
                 CDEBUG(D_INFO, "next ping in "CFS_DURATION_T" ("CFS_TIME_T")\n",
                                time_to_next_wake, time_of_next_wake);
 
index 57f0b81..ffc6add 100644 (file)
@@ -55,6 +55,9 @@ extern spinlock_t ptlrpc_rs_debug_lock;
 extern spinlock_t ptlrpc_all_services_lock;
 extern struct semaphore pinger_sem;
 extern struct semaphore ptlrpcd_sem;
+#ifdef __KERNEL__
+extern cfs_time_t pinger_next_wake;
+#endif
 
 __init int ptlrpc_init(void)
 {
@@ -68,6 +71,10 @@ __init int ptlrpc_init(void)
         init_mutex(&ptlrpcd_sem);
         ptlrpc_init_xid();
 
+#ifdef __KERNEL__
+        pinger_next_wake = 0;
+#endif
+
         rc = ptlrpc_init_portals();
         if (rc)
                 RETURN(rc);