IB/umad: Return EPOLLERR in case of when device disassociated
[ Upstream commitdef4cd43f5
] Currently, polling a umad device will always works, even if the device was disassociated. A disassociated device should immediately return EPOLLERR from poll(). Otherwise userspace is endlessly hung on poll() with no idea that the device has been removed from the system. Fixes:1da177e4c3
("Linux-2.6.12-rc2") Link: https://lore.kernel.org/r/20210125121339.837518-3-leon@kernel.org Signed-off-by: Shay Drory <shayd@nvidia.com> Signed-off-by: Leon Romanovsky <leonro@nvidia.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
16d7084da2
commit
c22944505c
@ -384,6 +384,11 @@ static ssize_t ib_umad_read(struct file *filp, char __user *buf,
|
|||||||
mutex_lock(&file->mutex);
|
mutex_lock(&file->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (file->agents_dead) {
|
||||||
|
mutex_unlock(&file->mutex);
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
packet = list_entry(file->recv_list.next, struct ib_umad_packet, list);
|
packet = list_entry(file->recv_list.next, struct ib_umad_packet, list);
|
||||||
list_del(&packet->list);
|
list_del(&packet->list);
|
||||||
|
|
||||||
@ -642,10 +647,14 @@ static __poll_t ib_umad_poll(struct file *filp, struct poll_table_struct *wait)
|
|||||||
/* we will always be able to post a MAD send */
|
/* we will always be able to post a MAD send */
|
||||||
__poll_t mask = EPOLLOUT | EPOLLWRNORM;
|
__poll_t mask = EPOLLOUT | EPOLLWRNORM;
|
||||||
|
|
||||||
|
mutex_lock(&file->mutex);
|
||||||
poll_wait(filp, &file->recv_wait, wait);
|
poll_wait(filp, &file->recv_wait, wait);
|
||||||
|
|
||||||
if (!list_empty(&file->recv_list))
|
if (!list_empty(&file->recv_list))
|
||||||
mask |= EPOLLIN | EPOLLRDNORM;
|
mask |= EPOLLIN | EPOLLRDNORM;
|
||||||
|
if (file->agents_dead)
|
||||||
|
mask = EPOLLERR;
|
||||||
|
mutex_unlock(&file->mutex);
|
||||||
|
|
||||||
return mask;
|
return mask;
|
||||||
}
|
}
|
||||||
@ -1262,6 +1271,7 @@ static void ib_umad_kill_port(struct ib_umad_port *port)
|
|||||||
list_for_each_entry(file, &port->file_list, port_list) {
|
list_for_each_entry(file, &port->file_list, port_list) {
|
||||||
mutex_lock(&file->mutex);
|
mutex_lock(&file->mutex);
|
||||||
file->agents_dead = 1;
|
file->agents_dead = 1;
|
||||||
|
wake_up_interruptible(&file->recv_wait);
|
||||||
mutex_unlock(&file->mutex);
|
mutex_unlock(&file->mutex);
|
||||||
|
|
||||||
for (id = 0; id < IB_UMAD_MAX_AGENTS; ++id)
|
for (id = 0; id < IB_UMAD_MAX_AGENTS; ++id)
|
||||||
|
Reference in New Issue
Block a user