On Tue, Jul 07, 2020 at 02:40:06PM -0600, Jens Axboe wrote: > >> so we have another 24 bytes before io_kiocb takes up another cacheline. > >> If that's a serious problem, I have an idea about how to shrink struct > >> kiocb by 8 bytes so struct io_rw would have space to store another > >> pointer. > > Yes, io_kiocb has room. Cache-locality wise whether that is fine or > > it must be placed within io_rw - I'll come to know once I get to > > implement this. Please share the idea you have, it can come handy. > > Except it doesn't, I'm not interested in adding per-request type fields > to the generic part of it. Before we know it, we'll blow past the next > cacheline. > > If we can find space in the kiocb, that'd be much better. Note that once > the async buffered bits go in for 5.9, then there's no longer a 4-byte > hole in struct kiocb. Well, poot, I was planning on using that. OK, how about this: +#define IOCB_NO_CMPL (15 << 28) struct kiocb { [...] - void (*ki_complete)(struct kiocb *iocb, long ret, long ret2); + loff_t __user *ki_uposp; - int ki_flags; + unsigned int ki_flags; +typedef void ki_cmpl(struct kiocb *, long ret, long ret2); +static ki_cmpl * const ki_cmpls[15]; +void ki_complete(struct kiocb *iocb, long ret, long ret2) +{ + unsigned int id = iocb->ki_flags >> 28; + + if (id < 15) + ki_cmpls[id](iocb, ret, ret2); +} +int kiocb_cmpl_register(void (*cb)(struct kiocb *, long, long)) +{ + for (i = 0; i < 15; i++) { + if (ki_cmpls[id]) + continue; + ki_cmpls[id] = cb; + return id; + } + WARN(); + return -1; +} ... etc, also need an unregister.