On Thu, Jun 18, 2020 at 11:37:51AM -0700, Matthew Wilcox wrote:
On Thu, Jun 18, 2020 at 08:23:33PM +0200, Uladzislau Rezki wrote:
quoted
quoted
+void vfree_bulk(size_t count, void **addrs)
+{
+ unsigned int i;
+
+ BUG_ON(in_nmi());
+ might_sleep_if(!in_interrupt());
+
+ for (i = 0; i < count; i++) {
+ void *addr = addrs[i];
+ kmemleak_free(addr);
+ if (addr)
+ __vfree(addr);
+ }
+}
+EXPORT_SYMBOL(vfree_bulk);
+
Can we just do addrs[i] all over the loop?
Also, we can just call vfree() instead that has all checking we
need: NMI, kmemleak, might_sleep.
Of course we _can_. But would we want to? This way, we only do these
checks once instead of once per pointer, which is rather the point
of batching.
Ahh, right. I briefly looked at it and missed that point. Right you
are we do not want the vfree() here!
I might actually go further and hoist the in_interrupt() check into
this function ...
Why do you need it? Just to inline below code:
<snip>
if (unlikely(in_interrupt()))
__vfree_deferred(addr);
else
__vunmap(addr, 1);
<snip>
and bypass the __vfree() call(that is not marked as inline one)?
I mean to inline above into vfree_bulk().
I suspect the RCU code always runs in_interrupt()
and so we always call vfree_deferred().
No. We release the memory from workqueue context.
--
Vlad Rezki