On 16/06/2020 22:21, Jens Axboe wrote: > > Nah this won't work, as the BE layout will be different. So how about > this, just add a 16-bit poll_events_hi instead. App/liburing will set > upper bits there. Something like the below, then just needs the > exclusive wait change on top. > > Only downside I can see is that newer applications on older kernels will > set EPOLLEXCLUSIVE but the kernel will ignore it. That's not a huge > concern for this particular bit, but could be a concern if there are > others that prove useful. > > diff --git a/fs/io_uring.c b/fs/io_uring.c > index de1175206807..a9d74330ad6b 100644 > --- a/fs/io_uring.c > +++ b/fs/io_uring.c > @@ -4809,6 +4809,9 @@ static int io_poll_add_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe > events = READ_ONCE(sqe->poll_events); > poll->events = demangle_poll(events) | EPOLLERR | EPOLLHUP; > > + if (READ_ONCE(sqe->poll_events_hi) & EPOLLEXCLUSIVE) poll_events_hi is 16 bit, EPOLLEXCLUSIVE is (1 << 28). It's always false. Do you look for something like below? union { ... __u32 fsync_flags; __u16 poll_events; /* compatibility */ __u32 poll32_events; /* word-reversed for BE */ }; u32 evs = READ_ONCE(poll32_events); if (BIG_ENDIAN) evs = swahw32(evs); // swap 16-bit halves // use as always, e.g. if (evs & EPOLLEXCLUSIVE) { ... } > + poll->events |= EPOLLEXCLUSIVE; > + > io_get_req_task(req); > return 0; > } > diff --git a/include/uapi/linux/io_uring.h b/include/uapi/linux/io_uring.h > index 92c22699a5a7..e6856d8e068f 100644 > --- a/include/uapi/linux/io_uring.h > +++ b/include/uapi/linux/io_uring.h > @@ -31,7 +31,10 @@ struct io_uring_sqe { > union { > __kernel_rwf_t rw_flags; > __u32 fsync_flags; > - __u16 poll_events; > + struct { > + __u16 poll_events; > + __u16 poll_events_hi; > + }; > __u32 sync_range_flags; > __u32 msg_flags; > __u32 timeout_flags; > -- Pavel Begunkov