mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] fork() failing
@ 2001-10-18 17:04 Marcelo Tosatti
  2001-10-18 19:25 ` David S. Miller
  0 siblings, 1 reply; 10+ messages in thread
From: Marcelo Tosatti @ 2001-10-18 17:04 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: lkml


Linus,

As you know, we currently allow 1-order allocations to fail easily. 

However, there is one special case of 1-order allocations which cannot
fail: fork.

Here is the tested patch against pre4.

--- linux.orig/mm/page_alloc.c	Thu Oct 18 14:26:28 2001
+++ linux/mm/page_alloc.c	Thu Oct 18 16:23:15 2001
@@ -393,8 +393,13 @@
 		}
 	}
 
-	/* Don't let big-order allocations loop */
-	if (order)
+	/* We have one special 1-order alloc user: fork().
+	 * It obviously cannot fail easily like other 
+	 * high order allocations. This could also be fixed
+	 * by having a __GFP_LOOP flag to indicate that the 
+	 * high order allocation is "critical". 
+	 */
+	if (order > 1)
 		return NULL;
 
 	/* Yield for kswapd, and try again */


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] fork() failing
  2001-10-18 19:25 ` David S. Miller
@ 2001-10-18 18:16   ` Marcelo Tosatti
  2001-10-18 19:50   ` Linus Torvalds
  1 sibling, 0 replies; 10+ messages in thread
From: Marcelo Tosatti @ 2001-10-18 18:16 UTC (permalink / raw)
  To: David S. Miller; +Cc: torvalds, linux-kernel



On Thu, 18 Oct 2001, David S. Miller wrote:

>    From: Marcelo Tosatti <marcelo@conectiva.com.br>
>    Date: Thu, 18 Oct 2001 15:04:15 -0200 (BRST)
>    
>    As you know, we currently allow 1-order allocations to fail easily. 
>    
>    However, there is one special case of 1-order allocations which cannot
>    fail: fork.
>    
>    Here is the tested patch against pre4.
> 
> There are also some platforms using 1-order allocations
> for page tables as well.
> 
> But I don't know if I agree with this special casing.
> Why not just put something into the GFP flag bits
> which distinguishes between high order allocations which
> are "critical" and others which are "don't try too hard".

Look at the comment on my patch. I've suggested that :)

I've added a __GFP_FAIL flag back in 2.4-ac something days exactly for
that purpose. I've ported the same code to the XFS tree so they could try
to "lazily" allocate (big) structures to build page clusters.

However, there is one nasty problem with it: How we can define "don't try
too hard" ?

Lets say you want to use the __GFP_FAIL flag when trying to allocate data
to do more readahead. If it fails too easily, we're never going to do
enough readahead.

What I'm trying to say is that we would need levels of "don't try too
hard" to have a nice scheme, and thats not simple.

See my point? 

> BTW, such a scheme could be useful for page cache pre-fetching.

It could be used in a _LOT_ of performance critical parts of the kernel,
indeed.

> If you use a high order allocation, it is more likely that all
> of the pages in that prefetch will fit into the same kernel TLB
> mapping.  We could use a GFP_NONCRITICAL for something like this.



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] fork() failing
  2001-10-18 19:50   ` Linus Torvalds
@ 2001-10-18 18:35     ` Marcelo Tosatti
  2001-10-18 20:05       ` Rik van Riel
  0 siblings, 1 reply; 10+ messages in thread
From: Marcelo Tosatti @ 2001-10-18 18:35 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: David S. Miller, linux-kernel



On Thu, 18 Oct 2001, Linus Torvalds wrote:

> 
> On Thu, 18 Oct 2001, David S. Miller wrote:
> >
> > There are also some platforms using 1-order allocations
> > for page tables as well.
> >
> > But I don't know if I agree with this special casing.
> 
> Well, it's not really any _new_ special casing - we've always had the
> special case for order-0, the patch just expands it to order-1 too.
> 
> That said, I think a separate flag saying "don't try too hard", which can
> be used for all orders, including 0 and 1, and just says that "ok, we want
> you to balance things, but if this allocation fails that's not a big
> deal".
> 
> So the flag would just always be implicit in allocations of higher orders,
> because big orders are basically impossible to guarantee..

Read my last mail on this thread... A single flag saying "we can fail
easily" does not sound good to me.

Imagine people changing the point where the 

	if ((gfp_mask & __GFP_FAIL))
		return;

check is done (inside the freeing routines).

I would like to have a _defined_ meaning for a "fail easily" allocation,
and a simple unique __GFP_FAIL flag can't give us that IMO.




^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] fork() failing
  2001-10-18 20:05       ` Rik van Riel
@ 2001-10-18 18:48         ` Marcelo Tosatti
  2001-10-18 20:15           ` Rik van Riel
  0 siblings, 1 reply; 10+ messages in thread
From: Marcelo Tosatti @ 2001-10-18 18:48 UTC (permalink / raw)
  To: Rik van Riel; +Cc: Linus Torvalds, David S. Miller, linux-kernel



On Thu, 18 Oct 2001, Rik van Riel wrote:

> On Thu, 18 Oct 2001, Marcelo Tosatti wrote:
> 
> > Imagine people changing the point where the
> >
> > 	if ((gfp_mask & __GFP_FAIL))
> > 		return;
> >
> > check is done (inside the freeing routines).
> >
> > I would like to have a _defined_ meaning for a "fail easily" allocation,
> > and a simple unique __GFP_FAIL flag can't give us that IMO.
> 
> Actually, I guess we could define this to be the same point
> where we'd end up freeing memory in order to satisfy our
> allocation.
> 
> This would result in __GFP_FAIL meaning "give me memory if
> it's available, but don't waste time freeing memory if we
> don't have enough free memory now".
> 
> Space-wise these semantics could change (say, pages_low
> vs. pages_min), but they'll stay the same when you look at
> "how hard to try" or "how much effort to spend".

Just remember that if we give __GFP_FAIL a "give me memory if its
available" meaning we simply can't use it for stuff like pagecache
prefetching --- its _too_ fragile.

Thats why I think we need the freeing levels, and thats why I think we
should left all of that for 2.5. :)




^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] fork() failing
  2001-10-18 20:15           ` Rik van Riel
@ 2001-10-18 19:07             ` Marcelo Tosatti
  2001-10-19  3:40               ` [RFC][PATCH] __GFP_FAIL (was: Re: [PATCH] fork() failing) Rik van Riel
  0 siblings, 1 reply; 10+ messages in thread
From: Marcelo Tosatti @ 2001-10-18 19:07 UTC (permalink / raw)
  To: Rik van Riel; +Cc: Linus Torvalds, David S. Miller, linux-kernel



On Thu, 18 Oct 2001, Rik van Riel wrote:

> On Thu, 18 Oct 2001, Marcelo Tosatti wrote:
> > On Thu, 18 Oct 2001, Rik van Riel wrote:
> 
> > > Actually, I guess we could define this to be the same point
> > > where we'd end up freeing memory in order to satisfy our
> > > allocation.
> >
> > Just remember that if we give __GFP_FAIL a "give me memory if its
> > available" meaning we simply can't use it for stuff like pagecache
> > prefetching --- its _too_ fragile.
> 
> IMHO it makes perfect sense, since at this point, one more
> allocation _will_ push us over the limit and let kswapd go
> to work to free up more memory.
> 
> We just need to make sure that the "wake up kswapd and maybe
> help free memory" point is EXACTLY the same as the __GFP_FAIL
> failure point.

Ok, great, that works fine. We can do that for 2.4, no problem.
 
> Unless off course I'm overlooking something ... in that case
> I'd appreciate it if you could point it out to me ;)

I would just like to have a _good_ scheme for this kind of "lazy
allocations" for 2.5 which can also be used by the page clustering code.

We really don't want the page clustering code to simply use a
"__GFP_FAIL" which fails so easily because we want performance.

Got my point? 


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] fork() failing
  2001-10-18 17:04 [PATCH] fork() failing Marcelo Tosatti
@ 2001-10-18 19:25 ` David S. Miller
  2001-10-18 18:16   ` Marcelo Tosatti
  2001-10-18 19:50   ` Linus Torvalds
  0 siblings, 2 replies; 10+ messages in thread
From: David S. Miller @ 2001-10-18 19:25 UTC (permalink / raw)
  To: marcelo; +Cc: torvalds, linux-kernel

   From: Marcelo Tosatti <marcelo@conectiva.com.br>
   Date: Thu, 18 Oct 2001 15:04:15 -0200 (BRST)
   
   As you know, we currently allow 1-order allocations to fail easily. 
   
   However, there is one special case of 1-order allocations which cannot
   fail: fork.
   
   Here is the tested patch against pre4.

There are also some platforms using 1-order allocations
for page tables as well.

But I don't know if I agree with this special casing.
Why not just put something into the GFP flag bits
which distinguishes between high order allocations which
are "critical" and others which are "don't try too hard".

BTW, such a scheme could be useful for page cache pre-fetching.
If you use a high order allocation, it is more likely that all
of the pages in that prefetch will fit into the same kernel TLB
mapping.  We could use a GFP_NONCRITICAL for something like this.

Franks a lot,
David S. Miller
davem@redhat.com

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] fork() failing
  2001-10-18 19:25 ` David S. Miller
  2001-10-18 18:16   ` Marcelo Tosatti
@ 2001-10-18 19:50   ` Linus Torvalds
  2001-10-18 18:35     ` Marcelo Tosatti
  1 sibling, 1 reply; 10+ messages in thread
From: Linus Torvalds @ 2001-10-18 19:50 UTC (permalink / raw)
  To: David S. Miller; +Cc: marcelo, linux-kernel


On Thu, 18 Oct 2001, David S. Miller wrote:
>
> There are also some platforms using 1-order allocations
> for page tables as well.
>
> But I don't know if I agree with this special casing.

Well, it's not really any _new_ special casing - we've always had the
special case for order-0, the patch just expands it to order-1 too.

That said, I think a separate flag saying "don't try too hard", which can
be used for all orders, including 0 and 1, and just says that "ok, we want
you to balance things, but if this allocation fails that's not a big
deal".

So the flag would just always be implicit in allocations of higher orders,
because big orders are basically impossible to guarantee..

		Linus


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] fork() failing
  2001-10-18 18:35     ` Marcelo Tosatti
@ 2001-10-18 20:05       ` Rik van Riel
  2001-10-18 18:48         ` Marcelo Tosatti
  0 siblings, 1 reply; 10+ messages in thread
From: Rik van Riel @ 2001-10-18 20:05 UTC (permalink / raw)
  To: Marcelo Tosatti; +Cc: Linus Torvalds, David S. Miller, linux-kernel

On Thu, 18 Oct 2001, Marcelo Tosatti wrote:

> Imagine people changing the point where the
>
> 	if ((gfp_mask & __GFP_FAIL))
> 		return;
>
> check is done (inside the freeing routines).
>
> I would like to have a _defined_ meaning for a "fail easily" allocation,
> and a simple unique __GFP_FAIL flag can't give us that IMO.

Actually, I guess we could define this to be the same point
where we'd end up freeing memory in order to satisfy our
allocation.

This would result in __GFP_FAIL meaning "give me memory if
it's available, but don't waste time freeing memory if we
don't have enough free memory now".

Space-wise these semantics could change (say, pages_low
vs. pages_min), but they'll stay the same when you look at
"how hard to try" or "how much effort to spend".

regards,

Rik
-- 
DMCA, SSSCA, W3C?  Who cares?  http://thefreeworld.net/  (volunteers needed)

http://www.surriel.com/		http://distro.conectiva.com/


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] fork() failing
  2001-10-18 18:48         ` Marcelo Tosatti
@ 2001-10-18 20:15           ` Rik van Riel
  2001-10-18 19:07             ` Marcelo Tosatti
  0 siblings, 1 reply; 10+ messages in thread
From: Rik van Riel @ 2001-10-18 20:15 UTC (permalink / raw)
  To: Marcelo Tosatti; +Cc: Linus Torvalds, David S. Miller, linux-kernel

On Thu, 18 Oct 2001, Marcelo Tosatti wrote:
> On Thu, 18 Oct 2001, Rik van Riel wrote:

> > Actually, I guess we could define this to be the same point
> > where we'd end up freeing memory in order to satisfy our
> > allocation.
>
> Just remember that if we give __GFP_FAIL a "give me memory if its
> available" meaning we simply can't use it for stuff like pagecache
> prefetching --- its _too_ fragile.

IMHO it makes perfect sense, since at this point, one more
allocation _will_ push us over the limit and let kswapd go
to work to free up more memory.

We just need to make sure that the "wake up kswapd and maybe
help free memory" point is EXACTLY the same as the __GFP_FAIL
failure point.

Unless off course I'm overlooking something ... in that case
I'd appreciate it if you could point it out to me ;)

regards,

Rik
-- 
DMCA, SSSCA, W3C?  Who cares?  http://thefreeworld.net/  (volunteers needed)

http://www.surriel.com/		http://distro.conectiva.com/


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [RFC][PATCH] __GFP_FAIL  (was: Re: [PATCH] fork() failing)
  2001-10-18 19:07             ` Marcelo Tosatti
@ 2001-10-19  3:40               ` Rik van Riel
  0 siblings, 0 replies; 10+ messages in thread
From: Rik van Riel @ 2001-10-19  3:40 UTC (permalink / raw)
  To: Marcelo Tosatti; +Cc: Linus Torvalds, David S. Miller, linux-kernel

On Thu, 18 Oct 2001, Marcelo Tosatti wrote:
> On Thu, 18 Oct 2001, Rik van Riel wrote:

> > We just need to make sure that the "wake up kswapd and maybe
> > help free memory" point is EXACTLY the same as the __GFP_FAIL
> > failure point.
>
> Ok, great, that works fine. We can do that for 2.4, no problem.

A quick (untested) patch to demonstrate my idea is below
my signature. Note the comments in __alloc_pages() ...
it's important to only fail our __GFP_FAIL allocation
_after_ having woken up kswapd.

regards,

Rik
-- 
DMCA, SSSCA, W3C?  Who cares?  http://thefreeworld.net/  (volunteers needed)

http://www.surriel.com/		http://distro.conectiva.com/



--- linux-2.4.12-ac3/mm/page_alloc.c.nofail	Thu Oct 18 23:24:50 2001
+++ linux-2.4.12-ac3/mm/page_alloc.c	Fri Oct 19 01:34:31 2001
@@ -341,18 +341,25 @@

 	/*
 	 * OK, none of the zones on our zonelist has lots
-	 * of pages free.
-	 *
-	 * We wake up kswapd, in the hope that kswapd will
-	 * resolve this situation before memory gets tight.
-	 *
-	 * We'll also help a bit trying to free pages, this
-	 * way statistics will make sure really fast allocators
-	 * are slowed down more than slow allocators and other
-	 * programs in the system shouldn't be impacted as much
-	 * by the hogs.
+	 * of pages free. Kswapd has work to do ...
 	 */
 	wakeup_kswapd();
+
+	/*
+	 * We don't want to do memory balancing work ourself,
+	 * instead we fail this allocation and hope that kswapd
+	 * will have things in a better shape next time.
+	 */
+	if (gfp_mask & __GFP_FAIL)
+		return NULL;
+
+	/*
+	 * Free some pages ourselves, rather than eating up the
+	 * last few free pages and running the system into the
+	 * ground.  Since this slows down heavy allocators more
+	 * than occasional allocators, it provides some fairness
+	 * and smoother behaviour under heavy load.
+	 */
 	if ((gfp_mask & __GFP_WAIT) && !(current->flags & PF_MEMALLOC))
 		try_to_free_pages(gfp_mask);

--- linux-2.4.12-ac3/include/linux/mm.h.nofail	Fri Oct 19 01:29:19 2001
+++ linux-2.4.12-ac3/include/linux/mm.h	Fri Oct 19 01:33:30 2001
@@ -567,12 +567,14 @@
 #define __GFP_HIGH	0x20	/* Should access emergency pools? */
 #define __GFP_IO	0x40	/* Can start physical IO? */
 #define __GFP_FS	0x80	/* Can call down to low-level FS? */
+#define __GFP_FAIL	0x100	/* Fail early when low on free pages. */

 #define GFP_NOIO	(__GFP_HIGH | __GFP_WAIT)
 #define GFP_NOFS	(__GFP_HIGH | __GFP_WAIT | __GFP_IO)
 #define GFP_ATOMIC	(__GFP_HIGH)
 #define GFP_USER	(             __GFP_WAIT | __GFP_IO | __GFP_FS)
 #define GFP_HIGHUSER	(             __GFP_WAIT | __GFP_IO | __GFP_FS | __GFP_HIGHMEM)
+#define GFP_READAHEAD	(             __GFP_WAIT | __GFP_IO | __GFP_FS | __GFP_HIGHMEM | __GFP_FAIL)
 #define GFP_KERNEL	(__GFP_HIGH | __GFP_WAIT | __GFP_IO | __GFP_FS)
 #define GFP_NFS		(__GFP_HIGH | __GFP_WAIT | __GFP_IO | __GFP_FS)
 #define GFP_KSWAPD	(                          __GFP_IO | __GFP_FS)


^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2001-10-19  3:40 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-10-18 17:04 [PATCH] fork() failing Marcelo Tosatti
2001-10-18 19:25 ` David S. Miller
2001-10-18 18:16   ` Marcelo Tosatti
2001-10-18 19:50   ` Linus Torvalds
2001-10-18 18:35     ` Marcelo Tosatti
2001-10-18 20:05       ` Rik van Riel
2001-10-18 18:48         ` Marcelo Tosatti
2001-10-18 20:15           ` Rik van Riel
2001-10-18 19:07             ` Marcelo Tosatti
2001-10-19  3:40               ` [RFC][PATCH] __GFP_FAIL (was: Re: [PATCH] fork() failing) Rik van Riel

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®