Re: [patch] my latest oom stuff

Andrea Arcangeli (andrea@e-mind.com)
Sat, 24 Oct 1998 20:30:05 +0200 (CEST)


On Sat, 24 Oct 1998, Andrea Arcangeli wrote:

>Index: linux/mm/page_alloc.c
>diff -u linux/mm/page_alloc.c:1.1.1.2 linux/mm/page_alloc.c:1.1.1.1.18.3
>--- linux/mm/page_alloc.c:1.1.1.2 Sat Oct 24 15:42:51 1998
>+++ linux/mm/page_alloc.c Sat Oct 24 17:42:01 1998
>@@ -237,45 +237,31 @@
> unsigned long __get_free_pages(int gfp_mask, unsigned long order)
> {
> unsigned long flags;
>+ int again = 0;
>+ int wait = gfp_mask & __GFP_WAIT;
>
> if (order >= NR_MEM_LISTS)
> goto nopage;
>
>- if (gfp_mask & __GFP_WAIT) {
>- if (in_interrupt()) {
>- static int count = 0;
>- if (++count < 5) {
>- printk("gfp called nonatomically from interrupt %p\n",
>- __builtin_return_address(0));
>- }
>- goto nopage;
>- }
>-
>- if (freepages.min > nr_free_pages) {
>- int freed;
>- freed = try_to_free_pages(gfp_mask, SWAP_CLUSTER_MAX);
>- /*
>- * Low priority (user) allocations must not
>- * succeed if we didn't have enough memory
>- * and we couldn't get more..
>- */
>- if (!freed && !(gfp_mask & (__GFP_MED | __GFP_HIGH)))
>- goto nopage;
>- }
>+ if (wait && in_interrupt()) {
>+ printk("gfp called nonatomically from interrupt %p\n",
>+ __builtin_return_address(0));
>+ goto nopage;
> }
>+ again:
> spin_lock_irqsave(&page_alloc_lock, flags);
> RMQUEUE(order, (gfp_mask & GFP_DMA));
> spin_unlock_irqrestore(&page_alloc_lock, flags);
>+
>+ kswapd_wakeup();
^^^^^^^^^^^^^^^^
>+
>+ if (!again && wait)
>+ {
>+ again = 1;
>+ if (try_to_free_pages(gfp_mask, 1 << order))
^^^^^^^^^^
>+ goto again;
>+ }
>
>- /*
>- * If we failed to find anything, we'll return NULL, but we'll
>- * wake up kswapd _now_ ad even wait for it synchronously if
>- * we can.. This way we'll at least make some forward progress
>- * over time.
>- */
>- wake_up(&kswapd_wait);
>- if (gfp_mask & __GFP_WAIT)
>- schedule();
> nopage:
> return 0;
> }
>

Woops excuse me, that was an experiment, all other part of the previous
patch are valid though. The right page_alloc patch is this:

Index: linux/mm/page_alloc.c
diff -u linux/mm/page_alloc.c:1.1.1.2 linux/mm/page_alloc.c:1.1.1.1.18.4
--- linux/mm/page_alloc.c:1.1.1.2 Sat Oct 24 15:42:51 1998
+++ linux/mm/page_alloc.c Sat Oct 24 20:25:17 1998
@@ -237,45 +237,29 @@
unsigned long __get_free_pages(int gfp_mask, unsigned long order)
{
unsigned long flags;
+ int again = 0;
+ int wait = gfp_mask & __GFP_WAIT;

if (order >= NR_MEM_LISTS)
goto nopage;

- if (gfp_mask & __GFP_WAIT) {
- if (in_interrupt()) {
- static int count = 0;
- if (++count < 5) {
- printk("gfp called nonatomically from interrupt %p\n",
- __builtin_return_address(0));
- }
- goto nopage;
- }
-
- if (freepages.min > nr_free_pages) {
- int freed;
- freed = try_to_free_pages(gfp_mask, SWAP_CLUSTER_MAX);
- /*
- * Low priority (user) allocations must not
- * succeed if we didn't have enough memory
- * and we couldn't get more..
- */
- if (!freed && !(gfp_mask & (__GFP_MED | __GFP_HIGH)))
- goto nopage;
- }
+ if (wait && in_interrupt()) {
+ printk("gfp called nonatomically from interrupt %p\n",
+ __builtin_return_address(0));
+ goto nopage;
}
+ again:
spin_lock_irqsave(&page_alloc_lock, flags);
RMQUEUE(order, (gfp_mask & GFP_DMA));
spin_unlock_irqrestore(&page_alloc_lock, flags);
+
+ if (!again && wait)
+ {
+ again = 1;
+ if (try_to_free_pages(gfp_mask, SWAP_CLUSTER_MAX))
+ goto again;
+ }

- /*
- * If we failed to find anything, we'll return NULL, but we'll
- * wake up kswapd _now_ ad even wait for it synchronously if
- * we can.. This way we'll at least make some forward progress
- * over time.
- */
- wake_up(&kswapd_wait);
- if (gfp_mask & __GFP_WAIT)
- schedule();
nopage:
return 0;
}

If you don' t want to cut-and-paste by hand the whole right patch is here:

ftp://e-mind.com/pub/linux/kernel-patches/arca-mm-2.1.126.diff

Andrea Arcangeli

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/