Jens Axboe <axboe@xxxxxxxxx> writes: > init_once is called when an object doesn't come from the cache, and > hence needs initial clearing of certain members. While the whole > struct could get cleared by memset() in that case, a few of the cache > members are large enough that this may cause unnecessary overhead if > the caches used aren't large enough to satisfy the workload. For those > cases, some churn of kmalloc+kfree is to be expected. > > Ensure that the 3 users that need clearing put the members they need > cleared at the start of the struct, and wrap the rest of the struct in > a struct group so the offset is known. > > While at it, improve the interaction with KASAN such that when/if > KASAN writes to members inside the struct that should be retained over > caching, it won't trip over itself. For rw and net, the retaining of > the iovec over caching is disabled if KASAN is enabled. A helper will > free and clear those members in that case. > > @@ -1813,11 +1798,10 @@ void io_netmsg_cache_free(const void *entry) > { > struct io_async_msghdr *kmsg = (struct io_async_msghdr *) entry; > > - if (kmsg->free_iov) { > - kasan_mempool_unpoison_object(kmsg->free_iov, > - kmsg->free_iov_nr * sizeof(struct iovec)); > +#if !defined(CONFIG_KASAN) > + if (kmsg->free_iov) > io_netmsg_iovec_free(kmsg); > - } > +#endif Among mostly ugly choices, this is an improvement over the init_once callback. I'd just fold the above codeguard into the code: if (IS_DEFINED(CONFIG_KASAN) && kmsg->free_iov) Other than that, Reviewed-by: Gabriel Krisman Bertazi <krisman@xxxxxxx> > kfree(kmsg); > } > #endif > diff --git a/io_uring/net.h b/io_uring/net.h > index 52bfee05f06a..b804c2b36e60 100644 > --- a/io_uring/net.h > +++ b/io_uring/net.h > @@ -5,16 +5,20 @@ > > struct io_async_msghdr { > #if defined(CONFIG_NET) > - struct iovec fast_iov; > - /* points to an allocated iov, if NULL we use fast_iov instead */ > struct iovec *free_iov; > + /* points to an allocated iov, if NULL we use fast_iov instead */ > int free_iov_nr; > - int namelen; > - __kernel_size_t controllen; > - __kernel_size_t payloadlen; > - struct sockaddr __user *uaddr; > - struct msghdr msg; > - struct sockaddr_storage addr; > + struct_group(clear, -- Gabriel Krisman Bertazi