From: Andrea Arcangeli <andrea@suse.de>
To: Linus Torvalds <torvalds@transmeta.com>
Cc: linux-kernel@vger.kernel.org
Subject: GFP_NOFS broken
Date: Thu, 5 Jul 2001 19:07:39 +0200 [thread overview]
Message-ID: <20010705190739.A704@athlon.random> (raw)
While I was travelling disconnected from the internet the last week (I
will buy a GPRS phone soon ;) I also spotted and fixed the __GFP_BUFFER
deadlock that I was triggering on my 128m laptop while browsing large
email folders on top of crypto loop:
--- 2.4.6pre6aa1/include/linux/mm.h.~1~ Sat Jun 30 00:49:54 2001
+++ 2.4.6pre6aa1/include/linux/mm.h Sat Jun 30 02:20:57 2001
@@ -538,9 +538,8 @@
#define __GFP_WAIT 0x10
#define __GFP_HIGH 0x20
#define __GFP_IO 0x40
-#define __GFP_BUFFER 0x80
-#define GFP_BUFFER (__GFP_HIGH | __GFP_WAIT | __GFP_BUFFER)
+#define GFP_BUFFER (__GFP_HIGH | __GFP_WAIT)
#define GFP_ATOMIC (__GFP_HIGH)
#define GFP_USER ( __GFP_WAIT | __GFP_IO)
#define GFP_HIGHUSER ( __GFP_WAIT | __GFP_IO | __GFP_HIGHMEM)
--- 2.4.6pre6aa1/include/linux/slab.h.~1~ Sat Jun 30 00:49:56 2001
+++ 2.4.6pre6aa1/include/linux/slab.h Sat Jun 30 02:21:09 2001
@@ -22,7 +22,7 @@
#define SLAB_NFS GFP_NFS
#define SLAB_DMA GFP_DMA
-#define SLAB_LEVEL_MASK (__GFP_WAIT|__GFP_HIGH|__GFP_IO|__GFP_BUFFER)
+#define SLAB_LEVEL_MASK (__GFP_WAIT|__GFP_HIGH|__GFP_IO)
#define SLAB_NO_GROW 0x00001000UL /* don't grow a cache */
/* flags to pass to kmem_cache_create().
--- 2.4.6pre6aa1/mm/vmscan.c.~1~ Sat Jun 30 00:44:36 2001
+++ 2.4.6pre6aa1/mm/vmscan.c Sat Jun 30 02:21:25 2001
@@ -425,7 +425,6 @@
*/
#define MAX_LAUNDER (4 * (1 << page_cluster))
#define CAN_DO_IO (gfp_mask & __GFP_IO)
-#define CAN_DO_BUFFERS (gfp_mask & __GFP_BUFFER)
int page_launder(int gfp_mask, int sync)
{
int launder_loop, maxscan, cleaned_pages, maxlaunder;
@@ -613,7 +612,7 @@
* loads, flush out the dirty pages before we have to wait on
* IO.
*/
- if ((CAN_DO_IO || CAN_DO_BUFFERS) && !launder_loop && free_shortage()) {
+ if (CAN_DO_IO && !launder_loop && free_shortage()) {
launder_loop = 1;
/* If we cleaned pages, never do synchronous IO. */
if (cleaned_pages)
However the more finegrined fix that I found in 2.4.7pre2 and 2.4.6
seems broken unlike my above one.
getblk called from the fs calls grow_buffers with GFP_NOFS which doesn't
inhibit shrink_dcache_memory to re-enter the fs in prune_dcache because
__GFP_IO is set. And it will deadlock as usual when shrink_dcache reenter
the fs that way.
This should cure the deadlock (against 2.4.7pre2) but beware it's
untested.
--- 2.4.7pre2aa1/fs/dcache.c.~1~ Thu Jul 5 17:13:50 2001
+++ 2.4.7pre2aa1/fs/dcache.c Thu Jul 5 18:52:03 2001
@@ -566,7 +566,7 @@
* We should make sure we don't hold the superblock lock over
* block allocations, but for now:
*/
- if (!(gfp_mask & __GFP_IO))
+ if (!(gfp_mask & __GFP_FS))
return;
if (priority)
--- 2.4.7pre2aa1/fs/inode.c.~1~ Thu Jul 5 17:13:48 2001
+++ 2.4.7pre2aa1/fs/inode.c Thu Jul 5 18:52:08 2001
@@ -696,7 +696,7 @@
* want to recurse into the FS that called us
* in clear_inode() and friends..
*/
- if (!(gfp_mask & __GFP_IO))
+ if (!(gfp_mask & __GFP_FS))
return;
if (priority)
Secondly this cleanups a bit in page_launder. If we are allowed to enter
the FS we can certainly also do I/O.
--- 2.4.7pre2aa1/mm/vmscan.c.~1~ Thu Jul 5 17:13:48 2001
+++ 2.4.7pre2aa1/mm/vmscan.c Thu Jul 5 18:59:33 2001
@@ -612,7 +612,7 @@
* loads, flush out the dirty pages before we have to wait on
* IO.
*/
- if ((CAN_DO_IO || CAN_DO_FS) && !launder_loop && free_shortage()) {
+ if (CAN_DO_IO && !launder_loop && free_shortage()) {
launder_loop = 1;
/* If we cleaned pages, never do synchronous IO. */
if (cleaned_pages)
I will include them in my next tree as it is at least certainly better
than the previous code.
Andrea
next reply other threads:[~2001-07-05 17:07 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2001-07-05 17:07 Andrea Arcangeli [this message]
2001-07-05 17:17 ` GFP_NOFS broken Linus Torvalds
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20010705190739.A704@athlon.random \
--to=andrea@suse.de \
--cc=linux-kernel@vger.kernel.org \
--cc=torvalds@transmeta.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.