Whamcloud - gitweb
Only interrupt after timeout in ptlrpc_queue_wait. Fixed bug 583214.
authorshaver <shaver>
Thu, 25 Jul 2002 23:34:18 +0000 (23:34 +0000)
committershaver <shaver>
Thu, 25 Jul 2002 23:34:18 +0000 (23:34 +0000)
lustre/include/linux/lustre_lib.h
lustre/ptlrpc/client.c

index 08ce7f4..60dd8b9 100644 (file)
@@ -404,6 +404,8 @@ static inline int obd_ioctl_getdata(char **buf, int *len, void *arg)
 /*
  * Like wait_event_interruptible, but we're only interruptible by KILL, INT, or
  * TERM.
+ *
+ * XXXshaver These are going away soon, I hope.
  */
 #define __l_wait_event_killable(wq, condition, ret)                          \
 do {                                                                         \
@@ -435,4 +437,31 @@ do {                                                                         \
         __ret;                                                          \
 })
 
+#define __l_wait_event_timeout(wq, condition, timeout, ret)                   \
+do {                                                                          \
+        wait_queue_t __wait;                                                  \
+        init_waitqueue_entry(&__wait, current);                               \
+                                                                              \
+        add_wait_queue(&wq, &__wait);                                         \
+        for (;;) {                                                            \
+                set_current_state(TASK_INTERRUPTIBLE);                        \
+                if (condition)                                                \
+                        break;                                                \
+                if (timeout)                                                  \
+                        schedule_timeout(timeout);                            \
+                else                                                          \
+                        schedule();                                           \
+        }                                                                     \
+        current->state = TASK_RUNNING;                                        \
+        remove_wait_queue(&wq, &__wait);                                      \
+} while(0)
+
+#define l_wait_event_timeout(wq, condition, timeout)                          \
+({                                                                            \
+        int __ret = 0;                                                        \
+        if (!(condition))                                                     \
+                __l_wait_event_timeout(wq, condition, timeout, __ret);        \
+        __ret;                                                                \
+})
+
 #endif /* _LUSTRE_LIB_H */
index 35ef237..b135afe 100644 (file)
@@ -261,6 +261,11 @@ static int ptlrpc_check_reply(struct ptlrpc_request *req)
         }
 
         if (req->rq_flags & PTL_RPC_FL_RESEND) { 
+                if (l_killable_pending(current)) {
+                        CERROR("-- INTR --\n");
+                        req->rq_flags |= PTL_RPC_FL_INTR;
+                        GOTO(out, rc = 1);
+                }
                 CERROR("-- RESEND --\n");
                 GOTO(out, rc = 1);
         }
@@ -270,8 +275,13 @@ static int ptlrpc_check_reply(struct ptlrpc_request *req)
                 GOTO(out, rc = 1);
         }
 
+        if (req->rq_flags & PTL_RPC_FL_TIMEOUT && l_killable_pending(current)) {
+                req->rq_flags |= PTL_RPC_FL_INTR;
+                GOTO(out, rc = 1);
+        }
 
-        if (CURRENT_TIME - req->rq_time >= req->rq_timeout) {
+        if (req->rq_timeout &&
+            (CURRENT_TIME - req->rq_time >= req->rq_timeout)) {
                 CERROR("-- REQ TIMEOUT ON CONNID %d XID %Ld --\n",
                        req->rq_connid, (unsigned long long)req->rq_xid);
                 /* clear the timeout */
@@ -280,22 +290,17 @@ static int ptlrpc_check_reply(struct ptlrpc_request *req)
                 req->rq_flags |= PTL_RPC_FL_TIMEOUT;
                 if (req->rq_client && req->rq_client->cli_recovd)
                         recovd_cli_fail(req->rq_client);
-                if (req->rq_level < LUSTRE_CONN_FULL)
+                if (req->rq_level < LUSTRE_CONN_FULL) {
                         rc = 1;
-                else
+                } else if (l_killable_pending(current)) {
+                        req->rq_flags |= PTL_RPC_FL_INTR;
+                        rc = 1;
+                } else {
                         rc = 0;
+                }
                 GOTO(out, rc);
         }
 
-        if (req->rq_timeout) { 
-                schedule_timeout(req->rq_timeout * HZ);
-        }
-
-        if (l_killable_pending(current)) {
-                req->rq_flags |= PTL_RPC_FL_INTR;
-                GOTO(out, rc = 1);
-        }
-
  out:
         CDEBUG(D_NET, "req = %p, rc = %d\n", req, rc);
         return rc;
@@ -459,7 +464,7 @@ void ptlrpc_restart_req(struct ptlrpc_request *req)
 
 int ptlrpc_queue_wait(struct ptlrpc_request *req)
 {
-        int rc = 0;
+        int rc = 0, timeout;
         struct ptlrpc_client *cli = req->rq_client;
         ENTRY;
 
@@ -503,7 +508,13 @@ int ptlrpc_queue_wait(struct ptlrpc_request *req)
         spin_unlock(&cli->cli_lock);
 
         CDEBUG(D_OTHER, "-- sleeping\n");
-        l_wait_event_killable(req->rq_wait_for_rep, ptlrpc_check_reply(req));
+        /*
+         * req->rq_timeout gets reset in the timeout case, and
+         * l_wait_event_timeout is a macro, so save the timeout value here.
+         */
+        timeout = req->rq_timeout * HZ;
+        l_wait_event_timeout(req->rq_wait_for_rep, ptlrpc_check_reply(req),
+                             timeout);
         CDEBUG(D_OTHER, "-- done\n");
 
         if (req->rq_flags & PTL_RPC_FL_RESEND) {
@@ -512,15 +523,15 @@ int ptlrpc_queue_wait(struct ptlrpc_request *req)
         }
 
         up(&cli->cli_rpc_sem);
-        if (req->rq_flags & PTL_RPC_FL_TIMEOUT)
-                GOTO(out, rc = -ETIMEDOUT);
-
         if (req->rq_flags & PTL_RPC_FL_INTR) {
                 /* Clean up the dangling reply buffers */
                 ptlrpc_abort(req);
                 GOTO(out, rc = -EINTR);
         }
 
+        if (req->rq_flags & PTL_RPC_FL_TIMEOUT)
+                GOTO(out, rc = -ETIMEDOUT);
+
         if (!(req->rq_flags & PTL_RPC_FL_REPLIED))
                 GOTO(out, rc = req->rq_status);