Tony,
On Thu, Jun 15, 2006 at 02:56:42PM -0700, Luck, Tony wrote:
> > If not, what is your opinion of the two approaches above?
>
> 1408 bytes of local storage out of a 4K stack on x86 sounds
> too big ... especially if you implement as suggested above:
>
For x86, I am not suggesting 8, but something smaller like 4.
Current struct size for PMD is 176 and PNMC is 48, we can trim
a few bytes out of the reserved fields. Unfortunately we cannot
come down to 128 (nice cache line size) for the PMD.
> someroutine(int count)
> {
> struct foo foo[8], *foop;
>
> if (count < 8)
> foop = foo;
> else
> foop = kmalloc(8*sizeof *foop, GFP_...);
>
> ....
> }
>
> The problem here is that you have already burned up a
> big patch of the stack with your local structure. So
> kmalloc() is called without much left. Most of the time
> this doesn't matter because kmalloc() will just give
> you a block from the slab without much further stack use.
>
> But if memory is low, then the kmalloc() call will trigger
> a much deeper stack sequence to try to free up some, and
> since you already used a bunch of stack, this may push
> you over the edge ... but you won't know unless your test
> suites happen to trigger a memory shortage that happens
> just as you make this pfm call with >8 count.
>
I understand your point. The alternative is as I described in
my previous E-mail to use an argument buffer per context.
But then you would have to use the following sequence:
someroutine(intfd, struct foo *foo, int count)
{
struct foo *foop;
ctx = get_ctx(fd);
size = count * sizeof(*foop);
spin_lock(&ctx->lock);
if (ctx->arg_buffer_size < sz) {
if (sz > sysctl.max_arg_size)
goto error;
if (ctx->arg_buffer)
kfree(arg_buffer);
ctx-> ctx_arg_buffer = kmalloc(sz);
ctx->arg_buffer_sze = sz;
}
foop = ctx->arg_buffer;
copy_from_user(foop, foo, sz);
local_irq_save(flags);
/* do the real work */
local_irq_restore(flags);
copy_to_user(foo, foop, sz);
spin_unlock(&ctx->lock);
....
}
But I am not sure you can really do copy_to/from with some locks held.
I know for sure you cannot do it with interrupts masked.
As I pointed out with this approacj, it is hard to protect against someone
creating NFILE contexts and allocating sysctl.max_arg_size for each.
Do you see a better alternative?
Thanks.
_______________________________________________
perfmon mailing list
[email protected]
http://www.hpl.hp.com/hosted/linux/mail-archives/perfmon/