Skip to content

Commit 62fab31

Browse files
yishaihrleon
authored andcommitted
IB/uverbs: Fix to consider event queue closing also upon non-blocking mode
Fix ib_uverbs_event_read() to consider event queue closing also upon non-blocking mode. Once the queue is closed (e.g. hot-plug flow) all the existing events are cleaned-up as part of ib_uverbs_free_event_queue(). An application that uses the non-blocking FD mode should get -EIO in that case to let it knows that the device was removed already. Otherwise, it can loose the indication that the device was removed and won't recover. As part of that, refactor the code to have a single flow with regards to 'is_closed' for both blocking and non-blocking modes. Fixes: 14e23bd ("RDMA/core: Fix locking in ib_uverbs_event_read") Reviewed-by: Maor Gottlieb <maorg@nvidia.com> Signed-off-by: Yishai Hadas <yishaih@nvidia.com> Link: https://lore.kernel.org/r/97b00116a1e1e13f8dc4ec38a5ea81cf8c030210.1685960567.git.leon@kernel.org Signed-off-by: Leon Romanovsky <leon@kernel.org>
1 parent 0cadb4d commit 62fab31

1 file changed

Lines changed: 5 additions & 7 deletions

File tree

drivers/infiniband/core/uverbs_main.c

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -222,8 +222,12 @@ static ssize_t ib_uverbs_event_read(struct ib_uverbs_event_queue *ev_queue,
222222
spin_lock_irq(&ev_queue->lock);
223223

224224
while (list_empty(&ev_queue->event_list)) {
225-
spin_unlock_irq(&ev_queue->lock);
225+
if (ev_queue->is_closed) {
226+
spin_unlock_irq(&ev_queue->lock);
227+
return -EIO;
228+
}
226229

230+
spin_unlock_irq(&ev_queue->lock);
227231
if (filp->f_flags & O_NONBLOCK)
228232
return -EAGAIN;
229233

@@ -233,12 +237,6 @@ static ssize_t ib_uverbs_event_read(struct ib_uverbs_event_queue *ev_queue,
233237
return -ERESTARTSYS;
234238

235239
spin_lock_irq(&ev_queue->lock);
236-
237-
/* If device was disassociated and no event exists set an error */
238-
if (list_empty(&ev_queue->event_list) && ev_queue->is_closed) {
239-
spin_unlock_irq(&ev_queue->lock);
240-
return -EIO;
241-
}
242240
}
243241

244242
event = list_entry(ev_queue->event_list.next, struct ib_uverbs_event, list);

0 commit comments

Comments
 (0)