On Mon, 2006-08-28 at 18:03 +0200, Indan Zupancic wrote: > On Mon, August 28, 2006 12:22, Peter Zijlstra said:
> >> > @@ -391,6 +391,7 @@ enum sock_flags { > >> > SOCK_RCVTSTAMP, /* %SO_TIMESTAMP setting */ > >> > SOCK_LOCALROUTE, /* route locally only, %SO_DONTROUTE setting */ > >> > SOCK_QUEUE_SHRUNK, /* write queue has been shrunk recently */ > >> > + SOCK_VMIO, /* promise to never block on receive */ > >> > >> It might be used for IO related to the VM, but that doesn't tell _what_ it > >> does. > >> It also does much more than just not blocking on receive, so overal, aren't > >> both the vmio name and the comment slightly misleading? > > > > I'm so having trouble with this name; I had SOCK_NONBLOCKING for a > > while, but that is a very bad name because nonblocking has this well > > defined meaning when talking about sockets, and this is not that. > > > > Hence I came up with the VMIO, because that is the only selecting > > criteria for being special. - I'll fix up the comment. > > It's nice and short, but it might be weird if someone after a while finds > another way > of using this stuff. And it's relation to 'emergency' looks unclear. So maybe > calling > both the same makes most sense, no matter how you name it. I've tried to come up with another use-case, but failed (of course that doesn't mean there is no). Also, I'm really past caring what the thing is called ;-) But if ppl object I guess its easy enough to run yet another sed command over the patches. > >> > @@ -82,6 +82,7 @@ EXPORT_SYMBOL(zone_table); > >> > > >> > static char *zone_names[MAX_NR_ZONES] = { "DMA", "DMA32", "Normal", > >> > "HighMem" }; > >> > int min_free_kbytes = 1024; > >> > +int var_free_kbytes; > >> > >> Using var_free_pages makes the code slightly simpler, as all that needless > >> convertion isn't needed anymore. Perhaps the same is true for > >> min_free_kbytes... > > > > 't seems I'm a bit puzzled as to what you mean here. > > I mean to store the variable reserve in pages instead of kilobytes. Currently > you're > converting from the one to the other both when setting and when using the > value. That > doesn't make much sense and can be avoided by storing the value in pages from > the start. right, will have a peek. > void kfree_skbmem(struct sk_buff *skb) > { > struct sk_buff *other; > atomic_t *fclone_ref; > struct kmem_cache *cache = skbuff_head_cache; > struct sk_buff *free = skb; > > skb_release_data(skb); > switch (skb->fclone) { > case SKB_FCLONE_UNAVAILABLE: > goto free; > > case SKB_FCLONE_ORIG: > fclone_ref = (atomic_t *) (skb + 2); > if (atomic_dec_and_test(fclone_ref)){ > cache = skbuff_fclone_cache; > goto free; > } > break; > > case SKB_FCLONE_CLONE: > fclone_ref = (atomic_t *) (skb + 1); > other = skb - 1; > > /* The clone portion is available for > * fast-cloning again. > */ > skb->fclone = SKB_FCLONE_UNAVAILABLE; > > if (atomic_dec_and_test(fclone_ref)){ > cache = skbuff_fclone_cache; > free = other; > goto free; > } > break; > }; > return; > free: > if (!skb->emergency) > kmem_cache_free(cache, free); > else > emergency_rx_free(free, kmem_cache_size(cache)); > } Ah, like so, sure, that looks good. > >> You can get rid of the memalloc_reserve and vmio_request_queues variables > >> if you want, they aren't really needed for anything. If using them reduces > >> the total code size I'd keep them though. > > > > I find my version easier to read, but that might just be the way my > > brain works. > > Maybe true, but I believe my version is more natural in the sense that it > makes > more clear what the code is doing. Less bookkeeping, more real work, so to > speak. Ok, I'll have another look at it, perhaps my gray matter has shifted ;-) > But after another look things seem a bit shaky, in the locking corner anyway. > > sk_adjust_memalloc() calls adjust_memalloc_reserve(), which changes > var_free_kbytes > and then calls setup_per_zone_pages_min(), which does the real work. But it > reads > min_free_kbytes without holding any locks. In mainline that's fine as the > function > is only called by the proc handler and in obscure memory hotplug stuff. But > with > your code it can also be called at any moment when a VMIO socket is made, > which now > races with the proc callback. More a theoretical than a real problem, but > still > slightly messy. Knew about that, hadn't made up my mind on a fix yet. Good spot never the less. Time to actually fix it I guess. > adjust_memalloc_reserve() has no locking at all, while it might be called > concurrently > from different sources. Luckily sk_adjust_memalloc() is the only user, and > which uses > its own spinlock for synchronization, so things go well by accident now. It > seems > cleaner to move that spinlock so that it protects var|min_free_kbytes instead. Ah, no accident there, I'm fully aware that there would need to be a spinlock in adjust_memalloc_reserve() if there were another caller. (I even had it there for some time) - added comment. > +int adjust_memalloc_reserve(int pages) > +{ > + int kbytes; > + int err = 0; > + > + kbytes = var_free_kbytes + (pages << (PAGE_SHIFT - 10)); > + if (kbytes < 0) { > + err = -EINVAL; > + goto out; > + } > > Shouldn't that be a BUG_ON instead? Yeah, might as well be. - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html