On Thu, Feb 21, 2019 at 08:15:23AM +0000, Al Viro wrote: > All instances of struct socket are embedded into some > bigger structure - most into struct socket_alloc (with struct inode > following struct socket), some into struct tun_file or struct > tap_queue. > > In the last two cases the corresponding struct socket_wq > (the one whose address goes into socket->wq) is in the same > containing structure, right after struct socket. > > In case of struct socket_alloc, we allocate struct > socket_wq separately and set socket->wq before anyone sees > either (in sock_alloc_inode()). In sock_destroy_inode() > they are both freed (struct sock_alloc immediately, > struct socket_wq - RCU-delayed). > > AFAICS, nothing ever reassigns socket->wq. Could we > simply embed struct socket_wq into struct socket? RCU delay > is not an issue - net/socket.c is non-modular, so call_rcu()-based > variant freeing both together is not horrible. sock_alloc_inode() > would be simplified, tun/tap uses would simply lose the separate > socket_wq members. > > The only problem I see here is ____cacheline_aligned_in_smp > we have on struct socket_wq. Could we simply make it the first > field in struct socket? Without lockdep they are reasonably small - > on amd64 socket_wq is 64 bytes, while the rest of struct socket is > 48 (and pointer to wq would obviously disappear). > > Or is there something subtle I'm missing here?
Put it another way, what was the reason for "net: sock_def_readable() and friends RCU conversion" not to put RCU delay into freeing of struct socket itself? Separating the write-often fields from mostly read-only ones? I hadn't been able to find in archives the discussion from back in 2010, unfortunately ;-/