[linux-cifs-client] Re: [PATCH] cifs: fix wait_for_response to time out sleeping processes correctly

wasrshi nimara warshinimara at gmail.com
Wed Nov 26 02:59:37 GMT 2008


Hi jeff,

WIll check this and get back you. Sorry for not responding earlier. Away on
vacation:)

I will also post my patch just in case.

warshi

On Tue, Nov 25, 2008 at 10:32 AM, Jeff Layton <jlayton at redhat.com> wrote:

> 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 at redhat.com>
> Cc: Wasrshi Nimara <warshinimara at gmail.com>
> ---
>  fs/cifs/cifsfs.c    |   37 -------------------------------------
>  fs/cifs/transport.c |    7 ++-----
>  2 files changed, 2 insertions(+), 42 deletions(-)
>
> diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
> index 7f87066..1bd03af 100644
> --- a/fs/cifs/cifsfs.c
> +++ b/fs/cifs/cifsfs.c
> @@ -66,7 +66,6 @@ unsigned int sign_CIFS_PDUs = 1;
>  extern struct task_struct *oplockThread; /* remove sparse warning */
>  struct task_struct *oplockThread = NULL;
>  /* extern struct task_struct * dnotifyThread; remove sparse warning */
> -static struct task_struct *dnotifyThread = NULL;
>  static const struct super_operations cifs_super_ops;
>  unsigned int CIFSMaxBufSize = CIFS_MAX_MSGSIZE;
>  module_param(CIFSMaxBufSize, int, 0);
> @@ -1049,32 +1048,6 @@ static int cifs_oplock_thread(void *dummyarg)
>        return 0;
>  }
>
> -static int cifs_dnotify_thread(void *dummyarg)
> -{
> -       struct list_head *tmp;
> -       struct TCP_Server_Info *server;
> -
> -       do {
> -               if (try_to_freeze())
> -                       continue;
> -               set_current_state(TASK_INTERRUPTIBLE);
> -               schedule_timeout(15*HZ);
> -               /* check if any stuck requests that need
> -                  to be woken up and wakeq so the
> -                  thread can wake up and error out */
> -               read_lock(&cifs_tcp_ses_lock);
> -               list_for_each(tmp, &cifs_tcp_ses_list) {
> -                       server = list_entry(tmp, struct TCP_Server_Info,
> -                                        tcp_ses_list);
> -                       if (atomic_read(&server->inFlight))
> -                               wake_up_all(&server->response_q);
> -               }
> -               read_unlock(&cifs_tcp_ses_lock);
> -       } while (!kthread_should_stop());
> -
> -       return 0;
> -}
> -
>  static int __init
>  init_cifs(void)
>  {
> @@ -1151,17 +1124,8 @@ init_cifs(void)
>                goto out_unregister_dfs_key_type;
>        }
>
> -       dnotifyThread = kthread_run(cifs_dnotify_thread, NULL,
> "cifsdnotifyd");
> -       if (IS_ERR(dnotifyThread)) {
> -               rc = PTR_ERR(dnotifyThread);
> -               cERROR(1, ("error %d create dnotify thread", rc));
> -               goto out_stop_oplock_thread;
> -       }
> -
>        return 0;
>
> - out_stop_oplock_thread:
> -       kthread_stop(oplockThread);
>  out_unregister_dfs_key_type:
>  #ifdef CONFIG_CIFS_DFS_UPCALL
>        unregister_key_type(&key_type_dns_resolver);
> @@ -1200,7 +1164,6 @@ exit_cifs(void)
>        cifs_destroy_mids();
>        cifs_destroy_request_bufs();
>        kthread_stop(oplockThread);
> -       kthread_stop(dnotifyThread);
>  }
>
>  MODULE_AUTHOR("Steve French <sfrench at us.ibm.com>");
> diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
> index 8e0d1c3..6c1e10c 100644
> --- a/fs/cifs/transport.c
> +++ b/fs/cifs/transport.c
> @@ -410,11 +410,8 @@ static int wait_for_response(struct cifsSesInfo *ses,
>
>        for (;;) {
>                curr_timeout = timeout + jiffies;
> -               wait_event(ses->server->response_q,
> -                       (!(midQ->midState == MID_REQUEST_SUBMITTED)) ||
> -                       time_after(jiffies, curr_timeout) ||
> -                       ((ses->server->tcpStatus != CifsGood) &&
> -                        (ses->server->tcpStatus != CifsNew)));
> +               wait_event_timeout(ses->server->response_q,
> +                       midQ->midState != MID_REQUEST_SUBMITTED, timeout);
>
>                if (time_after(jiffies, curr_timeout) &&
>                        (midQ->midState == MID_REQUEST_SUBMITTED) &&
> --
> 1.5.5.1
>
>
-------------- next part --------------
HTML attachment scrubbed and removed


More information about the linux-cifs-client mailing list