aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/transport.c
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2008-12-05 20:41:21 -0500
committerSteve French <sfrench@us.ibm.com>2008-12-25 21:29:11 -0500
commit85705524258f93a6086c3247a58f34a661b82b3d (patch)
tree8cd8f39a92f649e5bce8001331e9b5a8a4c9e650 /fs/cifs/transport.c
parent8be0ed44c2fa4afcf2c6d2fb3102c926e9f989df (diff)
cifs: fix wait_for_response to time out sleeping processes correctly
cifs: fix wait_for_response to time out sleeping processes correctly The current scheme that CIFS uses to sleep and wait for a response is not quite what we want. After sending a request, wait_for_response puts the task to sleep with wait_event(). One of the conditions for wait_event is a timeout (using time_after()). The problem with this is that there is no guarantee that the process will ever be woken back up. If the server stops sending data, then cifs_demultiplex_thread will leave its response queue sleeping. I think the only thing that saves us here is the fact that cifs_dnotify_thread periodically (every 15s) wakes up sleeping processes on all response_q's that have calls in flight. This makes for unnecessary wakeups of some processes. It also means large variability in the timeouts since they're all woken up at once. Instead of this, put the tasks to sleep with wait_event_timeout. This makes them wake up on their own if they time out. With this change, cifs_dnotify_thread should no longer be needed. I've been testing this in conjunction with some other patches that I'm working on. It doesn't seem to affect performance at all with with heavy I/O. Identical iozone -ac runs complete in almost exactly the same time (<1% difference in times). Thanks to Wasrshi Nimara for initially pointing this out. Wasrshi, it would be nice to know whether this patch also helps your testcase. Signed-off-by: Jeff Layton <jlayton@redhat.com> Cc: Wasrshi Nimara <warshinimara@gmail.com> Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/cifs/transport.c')
-rw-r--r--fs/cifs/transport.c7
1 files changed, 2 insertions, 5 deletions
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
index cd4ed65d6cd9..4d076be46d90 100644
--- a/fs/cifs/transport.c
+++ b/fs/cifs/transport.c
@@ -410,11 +410,8 @@ static int wait_for_response(struct cifsSesInfo *ses,
410 410
411 for (;;) { 411 for (;;) {
412 curr_timeout = timeout + jiffies; 412 curr_timeout = timeout + jiffies;
413 wait_event(ses->server->response_q, 413 wait_event_timeout(ses->server->response_q,
414 (!(midQ->midState == MID_REQUEST_SUBMITTED)) || 414 midQ->midState != MID_REQUEST_SUBMITTED, timeout);
415 time_after(jiffies, curr_timeout) ||
416 ((ses->server->tcpStatus != CifsGood) &&
417 (ses->server->tcpStatus != CifsNew)));
418 415
419 if (time_after(jiffies, curr_timeout) && 416 if (time_after(jiffies, curr_timeout) &&
420 (midQ->midState == MID_REQUEST_SUBMITTED) && 417 (midQ->midState == MID_REQUEST_SUBMITTED) &&