Re: [PATCH 2/2] cifs: when CONFIG_HIGHMEM is set, serialize the read/write kmaps

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



2012/7/11 Jeff Layton <jlayton@xxxxxxxxxx>:
> Jian found that when he ran fsx on a 32 bit arch with a large wsize the
> process and one of the bdi writeback kthreads would sometimes deadlock
> with a stack trace like this:
>
> crash> bt
> PID: 2789   TASK: f02edaa0  CPU: 3   COMMAND: "fsx"
>  #0 [eed63cbc] schedule at c083c5b3
>  #1 [eed63d80] kmap_high at c0500ec8
>  #2 [eed63db0] cifs_async_writev at f7fabcd7 [cifs]
>  #3 [eed63df0] cifs_writepages at f7fb7f5c [cifs]
>  #4 [eed63e50] do_writepages at c04f3e32
>  #5 [eed63e54] __filemap_fdatawrite_range at c04e152a
>  #6 [eed63ea4] filemap_fdatawrite at c04e1b3e
>  #7 [eed63eb4] cifs_file_aio_write at f7fa111a [cifs]
>  #8 [eed63ecc] do_sync_write at c052d202
>  #9 [eed63f74] vfs_write at c052d4ee
> #10 [eed63f94] sys_write at c052df4c
> #11 [eed63fb0] ia32_sysenter_target at c0409a98
>     EAX: 00000004  EBX: 00000003  ECX: abd73b73  EDX: 012a65c6
>     DS:  007b      ESI: 012a65c6  ES:  007b      EDI: 00000000
>     SS:  007b      ESP: bf8db178  EBP: bf8db1f8  GS:  0033
>     CS:  0073      EIP: 40000424  ERR: 00000004  EFLAGS: 00000246
>
> Each task would kmap part of its address array before getting stuck, but
> not enough to actually issue the write.
>
> This patch fixes this by serializing the marshal_iov operations for
> async reads and writes. The idea here is to ensure that cifs
> aggressively tries to populate a request before attempting to fulfill
> another one. As soon as all of the pages are kmapped for a request, then
> we can unlock and allow another one to proceed.
>
> There's no need to do this serialization on non-CONFIG_HIGHMEM arches
> however, so optimize all of this out when CONFIG_HIGHMEM isn't set.
>
> Cc: <stable@xxxxxxxxxxxxxxx>
> Reported-by: Jian Li <jiali@xxxxxxxxxx>
> Signed-off-by: Jeff Layton <jlayton@xxxxxxxxxx>
> ---
>  fs/cifs/cifssmb.c |   30 +++++++++++++++++++++++++++++-
>  1 files changed, 29 insertions(+), 1 deletions(-)
>
> diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
> index 0170ee8..684a072 100644
> --- a/fs/cifs/cifssmb.c
> +++ b/fs/cifs/cifssmb.c
> @@ -86,7 +86,31 @@ static struct {
>  #endif /* CONFIG_CIFS_WEAK_PW_HASH */
>  #endif /* CIFS_POSIX */
>
> -/* Forward declarations */
> +#ifdef CONFIG_HIGHMEM
> +/*
> + * On arches that have high memory, kmap address space is limited. By
> + * serializing the kmap operations on those arches, we ensure that we don't
> + * end up with a bunch of threads in writeback with partially mapped page
> + * arrays, stuck waiting for kmap to come back. That situation prevents
> + * progress and can deadlock.
> + */
> +static DEFINE_MUTEX(cifs_kmap_mutex);
> +
> +static inline void
> +cifs_kmap_lock(void)
> +{
> +       mutex_lock(&cifs_kmap_mutex);
> +}
> +
> +static inline void
> +cifs_kmap_unlock(void)
> +{
> +       mutex_unlock(&cifs_kmap_mutex);
> +}
> +#else /* !CONFIG_HIGHMEM */
> +#define cifs_kmap_lock() do { ; } while(0)

checkpatch.pl raises the "ERROR: space required before the open
parenthesis '('" error.

> +#define cifs_kmap_unlock() do { ; } while(0)

the same checkpatch.pl error.

> +#endif /* CONFIG_HIGHMEM */
>
>  /* Mark as invalid, all open files on tree connections since they
>     were closed when session to server was lost */
> @@ -1503,7 +1527,9 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
>         }
>
>         /* marshal up the page array */
> +       cifs_kmap_lock();
>         len = rdata->marshal_iov(rdata, data_len);
> +       cifs_kmap_unlock();
>         data_len -= len;
>
>         /* issue the read if we have any iovecs left to fill */
> @@ -2069,7 +2095,9 @@ cifs_async_writev(struct cifs_writedata *wdata)
>          * and set the iov_len properly for each one. It may also set
>          * wdata->bytes too.
>          */
> +       cifs_kmap_lock();
>         wdata->marshal_iov(iov, wdata);
> +       cifs_kmap_unlock();
>
>         cFYI(1, "async write at %llu %u bytes", wdata->offset, wdata->bytes);
>
> --
> 1.7.7.6
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-cifs" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html



-- 
Best regards,
Pavel Shilovsky.
--
To unsubscribe from this list: send the line "unsubscribe linux-cifs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux