Bug 142959 - kswapd may calls wakeup_kswapd() recursively
kswapd may calls wakeup_kswapd() recursively
Status: CLOSED ERRATA
Product: Red Hat Enterprise Linux 3
Classification: Red Hat
Component: kernel (Show other bugs)
3.0
i686 Linux
medium Severity medium
: ---
: ---
Assigned To: Larry Woodman
Brian Brock
:
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2004-12-15 08:08 EST by Yasuma Takeda
Modified: 2007-11-30 17:07 EST (History)
2 users (show)

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2004-12-20 15:57:00 EST
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:


Attachments (Terms of Use)

  None (edit)
Description Yasuma Takeda 2004-12-15 08:08:02 EST
Description of problem:

I found a problem about kswapd. This problem causes a system stall.

int try_to_free_pages(unsigned int gfp_mask)
{
        int ret = 1;

        gfp_mask = pf_gfp_mask(gfp_mask);
        if (gfp_mask & __GFP_WAIT) {
                current->flags |= PF_MEMALLOC;
                ret = do_try_to_free_pages(gfp_mask);
                current->flags &= ~PF_MEMALLOC;
        }

        return ret;
}

If kswapd call try_to_free_pages(), the PF_MEMALLOC flag is lost.
Under heavy memory pressure, kswapd may fail to call getblk() 
and call free_more_memory().
The free_more_memory() calls try_to_free_pages().
As a result, the kswapd loses the PF_MEMALLOC flag.

diff -uNr linux.org/mm/vmscan.c linux/mm/vmscan.c
--- linux.org/mm/vmscan.c       2004-12-13 14:46:03.000000000 +0900
+++ linux/mm/vmscan.c   2004-12-13 14:52:22.000000000 +0900
@@ -1273,6 +1273,7 @@
 int try_to_free_pages(unsigned int gfp_mask)
 {
        int ret = 1;
+       unsigned long pf_flags = current->flags & PF_MEMALLOC;

        gfp_mask = pf_gfp_mask(gfp_mask);
        if (gfp_mask & __GFP_WAIT) {
@@ -1281,6 +1282,8 @@
                current->flags &= ~PF_MEMALLOC;
        }

+        current->flags |= pf_flags;
+
        return ret;
 }


Version-Release number of selected component (if applicable):
kernel-2.4.21-20.EL

How reproducible:
It needs heavy memory pressure.
It is difficult to reproduce this problem.
Comment 1 Larry Woodman 2004-12-15 09:12:41 EST
Fixed in RHEL3-U4:

int try_to_free_pages(unsigned int gfp_mask)
{
        int ret = 0;
                                                                     
                                            
        gfp_mask = pf_gfp_mask(gfp_mask);
        if (gfp_mask & __GFP_WAIT) {
                if (!(current->flags & PF_MEMALLOC)) {
                        current->flags |= PF_MEMALLOC;
                        ret = do_try_to_free_pages(gfp_mask);
                        current->flags &= ~PF_MEMALLOC;
                } else if (gfp_mask & (__GFP_IO | __GFP_FS))
                        ret = do_try_to_free_pages(gfp_mask &
~(__GFP_IO | __GFP_FS));
        }
                                                                     
                                            
        return ret;
}
Comment 2 Ernie Petrides 2004-12-15 17:33:37 EST
A fix for this problem was committed to the RHEL3 U4 patch pool
on 10-Sep-2004 (in kernel version 2.4.21-20.5.EL).
Comment 3 John Flanagan 2004-12-20 15:57:01 EST
An errata has been issued which should help the problem 
described in this bug report. This report is therefore being 
closed with a resolution of ERRATA. For more information
on the solution and/or where to find the updated files, 
please follow the link below. You may reopen this bug report 
if the solution does not work for you.

http://rhn.redhat.com/errata/RHBA-2004-550.html

Note You need to log in before you can comment on or make changes to this bug.