Re: Stability (2.2.14/15/16/17pre1)

From: Andrea Arcangeli (andrea@suse.de)
Date: Wed Jun 14 2000 - 16:53:39 EST


On Wed, 14 Jun 2000, Rik van Riel wrote:

>If one application is sleeping in try_to_free_pages (doing
>IO or somesuch), we must make sure that other programs in
>the system do not just allocate all the memory that the
>process in try_to_free_pages has just freed.

I think to see what the problem was but 2.2.16 isn't fixing the problem.
What I'm trying to say is that with such code you just raised
freepages.min not more than freepages.high.

I quote 2.2.16:

        if (!(current->flags & PF_MEMALLOC)) {
                int freed;
                extern struct wait_queue * kswapd_wait;

                if (nr_free_pages > freepages.high)
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                        goto ok_to_allocate;
                
                /* Maybe wake up kswapd for background swapping. */
                if (time_before(last_woke_kswapd + HZ, jiffies)) {
                        last_woke_kswapd = jiffies;
                        wake_up_interruptible(&kswapd_wait);
                }

                /* Somebody needs to free pages so we free some of our own. */
                if (atomic_read(&free_before_allocate)) {
                        current->flags |= PF_MEMALLOC;
                        freed = try_to_free_pages(gfp_mask);
                        current->flags &= ~PF_MEMALLOC;
                        if (freed)
                                goto ok_to_allocate;
                }

As far as the nr_free_pages is over freepages.high (you may have 20
process that are trying to free memory at the same time ok?) then
everybody is allowed to eat the pages without blocking while such 20
process are freeing their memory. When such 20 processes will return and
the nr_free_pages will be again only a mere freepages.high that isn't
enough to succeed all the allocations.

I guess what you wanted to do is instead something like:

        if (!(current->flags & PF_MEMALLOC)) {
                int freed;
                extern struct wait_queue * kswapd_wait;

                /* Somebody needs to free pages so we free some of our own. */
                if (atomic_read(&free_before_allocate)) {
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ do this check first
                        current->flags |= PF_MEMALLOC;
                        freed = try_to_free_pages(gfp_mask);
                        current->flags &= ~PF_MEMALLOC;
                        if (freed)
                                goto ok_to_allocate;
                }

                if (nr_free_pages > freepages.high)
                        goto ok_to_allocate;

The above is fondamentally different and it would make more sense to
me.

Comments?

Andrea

-
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/



This archive was generated by hypermail 2b29 : Thu Jun 15 2000 - 21:00:33 EST