From: Kirill Korotaev <dev@openvz.org>
To: Andrew Morton <akpm@osdl.org>
Cc: linux-kernel@vger.kernel.org, devel@openvz.org, kuznet@ms2.inr.ac.ru
Subject: Re: [PATCH] fdset's leakage
Date: Tue, 11 Jul 2006 13:05:03 +0400 [thread overview]
Message-ID: <44B369BF.6000104@openvz.org> (raw)
In-Reply-To: <20060711010104.16ed5d4b.akpm@osdl.org>
Andrew,
>>Another patch from Alexey Kuznetsov fixing memory leak in alloc_fdtable().
>>
>>[PATCH] fdset's leakage
>>
>>When found, it is obvious. nfds calculated when allocating fdsets
>>is rewritten by calculation of size of fdtable, and when we are
>>unlucky, we try to free fdsets of wrong size.
>>
>>Found due to OpenVZ resource management (User Beancounters).
>>
>>Signed-Off-By: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
>>Signed-Off-By: Kirill Korotaev <dev@openvz.org>
>>
>>
>>diff -urp linux-2.6-orig/fs/file.c linux-2.6/fs/file.c
>>--- linux-2.6-orig/fs/file.c 2006-07-10 12:10:51.000000000 +0400
>>+++ linux-2.6/fs/file.c 2006-07-10 14:47:01.000000000 +0400
>>@@ -277,11 +277,13 @@ static struct fdtable *alloc_fdtable(int
>> } while (nfds <= nr);
>> new_fds = alloc_fd_array(nfds);
>> if (!new_fds)
>>- goto out;
>>+ goto out2;
>> fdt->fd = new_fds;
>> fdt->max_fds = nfds;
>> fdt->free_files = NULL;
>> return fdt;
>>+out2:
>>+ nfds = fdt->max_fdset;
>> out:
>> if (new_openset)
>> free_fdset(new_openset, nfds);
>
>
> OK, that was a simple fix. And if we need this fix backported to 2.6.17.x
> then it'd be best to go with the simple fix.
>
> And I think we do need to backport this to 2.6.17.x because NR_OPEN can be
> really big, and vmalloc() is not immortal.
>
> But the code in there is really sick. In all cases we do:
>
> free_fdset(foo->open_fds, foo->max_fdset);
> free_fdset(foo->close_on_exec, foo->max_fdset);
>
> How much neater and more reliable would it be to do:
>
> free_fdsets(foo);
>
> ?
agree. should I prepare a patch?
> Also,
>
> nfds = NR_OPEN_DEFAULT;
> /*
> * Expand to the max in easy steps, and keep expanding it until
> * we have enough for the requested fd array size.
> */
> do {
> #if NR_OPEN_DEFAULT < 256
> if (nfds < 256)
> nfds = 256;
> else
> #endif
> if (nfds < (PAGE_SIZE / sizeof(struct file *)))
> nfds = PAGE_SIZE / sizeof(struct file *);
> else {
> nfds = nfds * 2;
> if (nfds > NR_OPEN)
> nfds = NR_OPEN;
> }
> } while (nfds <= nr);
>
>
> That's going to take a long time to compute if nr > NR_OPEN. I just fixed
> a similar infinite loop in this function. Methinks this
>
> nfds = max(NR_OPEN_DEFAULT, 256);
> nfds = max(nfds, PAGE_SIZE/sizeof(struct file *));
> nfds = max(nfds, round_up_pow_of_two(nr + 1));
> nfds = min(nfds, NR_OPEN);
>
> is clearer and less buggy. I _think_ it's also equivalent (as long as
> NR_OPEN>256). But please check my logic.
Yeah, I also noticed these nasty loops but was too lazy to bother :)
Too much crap for my nerves :)
Your logic looks fine for me. Do we have already round_up_pow_of_two() function or
should we create it as something like:
unsinged long round_up_pow_of_two(unsigned long x)
{
unsigned long res = 1 << BITS_PER_LONG;
while (res > x)
res >>= 1;
}
return res << 1;
}
or maybe using:
n = find_first_bit(x);
return res = 1 << n;
(though it depends on endianness IMHO)
?
Thanks,
Kirill
next prev parent reply other threads:[~2006-07-11 9:05 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-07-10 13:40 [PATCH] fdset's leakage Kirill Korotaev
2006-07-11 8:01 ` Andrew Morton
2006-07-11 9:02 ` Rene Scharfe
2006-07-11 9:05 ` Kirill Korotaev [this message]
2006-07-11 9:28 ` Andrew Morton
2006-07-11 16:13 ` Vadim Lobanov
2006-07-11 17:26 ` Eric Dumazet
2006-07-12 10:49 ` Kirill Korotaev
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=44B369BF.6000104@openvz.org \
--to=dev@openvz.org \
--cc=akpm@osdl.org \
--cc=devel@openvz.org \
--cc=kuznet@ms2.inr.ac.ru \
--cc=linux-kernel@vger.kernel.org \
/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.