Messages in this thread Patch in this message | | | From | Roman Penyaev <> | Subject | [RFC PATCH 13/15] epoll: support polling from userspace for ep_modify() | Date | Wed, 9 Jan 2019 17:40:23 +0100 |
| |
When epfd is polled from userspace and item is being modified:
1. Update user item with new pointer or poll flags. 2. Add event to user ring if needed.
Signed-off-by: Roman Penyaev <rpenyaev@suse.de> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Davidlohr Bueso <dbueso@suse.de> Cc: Jason Baron <jbaron@akamai.com> Cc: Al Viro <viro@zeniv.linux.org.uk> Cc: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Andrea Parri <andrea.parri@amarulasolutions.com> Cc: linux-fsdevel@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- fs/eventpoll.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-)
diff --git a/fs/eventpoll.c b/fs/eventpoll.c index 7732a8029a1c..2b38a3d884e8 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c @@ -2237,6 +2237,8 @@ static int ep_insert(struct eventpoll *ep, const struct epoll_event *event, static int ep_modify(struct eventpoll *ep, struct epitem *epi, const struct epoll_event *event) { + struct user_epitem *uitem; + __poll_t revents; int pwake = 0; poll_table pt; @@ -2251,6 +2253,13 @@ static int ep_modify(struct eventpoll *ep, struct epitem *epi, */ epi->event.events = event->events; /* need barrier below */ epi->event.data = event->data; /* protected by mtx */ + + /* Update user item, barrier is below */ + if (ep_polled_by_user(ep)) { + uitem = &ep->user_header->items[epi->bit]; + uitem->event = *event; + } + if (epi->event.events & EPOLLWAKEUP) { if (!ep_has_wakeup_source(epi)) ep_create_wakeup_source(epi); @@ -2284,12 +2293,19 @@ static int ep_modify(struct eventpoll *ep, struct epitem *epi, * If the item is "hot" and it is not registered inside the ready * list, push it inside. */ - if (ep_item_poll(epi, &pt, 1)) { + revents = ep_item_poll(epi, &pt, 1); + if (revents) { + bool added = false; + write_lock_irq(&ep->lock); - if (!ep_is_linked(epi)) { + if (ep_events_routed_to_uring(ep)) + added = ep_add_event_to_uring(epi, revents); + else if (!ep_is_linked(epi)) { list_add_tail(&epi->rdllink, &ep->rdllist); ep_pm_stay_awake(epi); - + added = true; + } + if (added) { /* Notify waiting tasks that events are available */ if (waitqueue_active(&ep->wq)) wake_up(&ep->wq); -- 2.19.1
| |