[linux-cifs-client] [PATCH 1/4] CIFS fixes for 2.4.x

Sergey Vlasov vsu at altlinux.ru
Thu Apr 8 15:48:06 GMT 2004


This patch fixes the deadlock between cifs_demultiplex_thread() and
SendReceive().  The following backtrace was observed:

Trace; d0a6b92f <[cifs]SendReceive+6f/3fe>
Trace; d0a5a959 <[cifs]smb_init+189/1a0>
Trace; d0a5b81c <[cifs]CIFSSMBWrite+14c/1b0>
Trace; d0a659c7 <[cifs]cifs_write+127/280>
Trace; d0a65cad <[cifs]cifs_partialpagewrite+18d/250>
Trace; c01e62f9 <memcpy_toiovec+39/70>
Trace; d0a65db8 <[cifs]cifs_writepage+48/a0>
Trace; c013115c <shrink_cache+21c/3c0>
Trace; c01313e2 <refill_inactive+e2/150>
Trace; c013147f <shrink_caches+2f/40>
Trace; c01314e2 <try_to_free_pages_zone+52/e0>
Trace; c013207d <balance_classzone+4d/230>
Trace; c013240a <__alloc_pages+1aa/2b0>
Trace; c0132520 <__get_free_pages+10/20>
Trace; c012fde7 <kmem_cache_grow+a7/210>
Trace; c0130019 <kmem_cache_alloc+c9/e0>
Trace; d0a6a230 <[cifs]checkSMB+90/100>
Trace; d0a6a23c <[cifs]checkSMB+9c/100>
Trace; d0a69f01 <[cifs]cifs_buf_get+11/30>
Trace; d0a5ff45 <[cifs]cifs_demultiplex_thread+85/5d0>
Trace; c0107126 <arch_kernel_thread+26/30>
Trace; d0a5fec0 <[cifs]cifs_demultiplex_thread+0/5d0>

The problem is that cifs_demultiplex_thread() allocates memory with
GFP_KERNEL, and such allocation can trigger writeout of dirty pages
if the system decides that there is not enough free memory.  If the
memory allocator decides to write out a dirty page to the same cifs
filesystem, this will eventually result in a call to SendReceive(),
which waits for server reply but never will get it because the
demultiplex thread is blocked.  This was the main cause of lockups
when writing large files.

This patch solves the problem in an easy way - it just sets
PF_MEMALLOC for the demultiplex thread, so that it will get the
memory without blocking.  In theory, it would be better to change
all GFP_KERNEL allocations which happen in context of this thread to
GFP_NOFS, but this requires a much larger patch and cannot be done
completely, because sock_create() always uses GFP_KERNEL internally;
therefore PF_MEMALLOC would be needed anyway.


--- kernel-source-cifs-1.0.2/connect.c.demux-memalloc	2004-02-05 05:55:30 +0300
+++ kernel-source-cifs-1.0.2/connect.c	2004-04-08 10:50:50 +0400
@@ -176,6 +176,7 @@ cifs_demultiplex_thread(struct TCP_Serve
 
 	daemonize();
 	sprintf(current->comm,"cifsd");
+	current->flags |= PF_MEMALLOC;
 	
 /*	allow_signal(SIGKILL);*/
 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
Url : http://lists.samba.org/archive/linux-cifs-client/attachments/20040408/9db50e0d/attachment.bin


More information about the linux-cifs-client mailing list