Skip to content

Commit 2fb4fb8

Browse files
mikijoysmb49
authored andcommitted
IB/core: Implement a limit on UMAD receive List
BugLink: https://bugs.launchpad.net/bugs/2077600 [ Upstream commit ca0b44e20a6f3032224599f02e7c8fb49525c894 ] The existing behavior of ib_umad, which maintains received MAD packets in an unbounded list, poses a risk of uncontrolled growth. As user-space applications extract packets from this list, the rate of extraction may not match the rate of incoming packets, leading to potential list overflow. To address this, we introduce a limit to the size of the list. After considering typical scenarios, such as OpenSM processing, which can handle approximately 100k packets per second, and the 1-second retry timeout for most packets, we set the list size limit to 200k. Packets received beyond this limit are dropped, assuming they are likely timed out by the time they are handled by user-space. Notably, packets queued on the receive list due to reasons like timed-out sends are preserved even when the list is full. Signed-off-by: Michael Guralnik <[email protected]> Reviewed-by: Mark Zhang <[email protected]> Link: https://lore.kernel.org/r/7197cb58a7d9e78399008f25036205ceab07fbd5.1713268818.git.leon@kernel.org Signed-off-by: Leon Romanovsky <[email protected]> Signed-off-by: Sasha Levin <[email protected]> Signed-off-by: Portia Stephens <[email protected]> Signed-off-by: Roxana Nicolescu <[email protected]>
1 parent cf44fc3 commit 2fb4fb8

File tree

1 file changed

+15
-6
lines changed

1 file changed

+15
-6
lines changed

drivers/infiniband/core/user_mad.c

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ MODULE_AUTHOR("Roland Dreier");
6363
MODULE_DESCRIPTION("InfiniBand userspace MAD packet access");
6464
MODULE_LICENSE("Dual BSD/GPL");
6565

66+
#define MAX_UMAD_RECV_LIST_SIZE 200000
67+
6668
enum {
6769
IB_UMAD_MAX_PORTS = RDMA_MAX_PORTS,
6870
IB_UMAD_MAX_AGENTS = 32,
@@ -113,6 +115,7 @@ struct ib_umad_file {
113115
struct mutex mutex;
114116
struct ib_umad_port *port;
115117
struct list_head recv_list;
118+
atomic_t recv_list_size;
116119
struct list_head send_list;
117120
struct list_head port_list;
118121
spinlock_t send_lock;
@@ -180,24 +183,28 @@ static struct ib_mad_agent *__get_agent(struct ib_umad_file *file, int id)
180183
return file->agents_dead ? NULL : file->agent[id];
181184
}
182185

183-
static int queue_packet(struct ib_umad_file *file,
184-
struct ib_mad_agent *agent,
185-
struct ib_umad_packet *packet)
186+
static int queue_packet(struct ib_umad_file *file, struct ib_mad_agent *agent,
187+
struct ib_umad_packet *packet, bool is_recv_mad)
186188
{
187189
int ret = 1;
188190

189191
mutex_lock(&file->mutex);
190192

193+
if (is_recv_mad &&
194+
atomic_read(&file->recv_list_size) > MAX_UMAD_RECV_LIST_SIZE)
195+
goto unlock;
196+
191197
for (packet->mad.hdr.id = 0;
192198
packet->mad.hdr.id < IB_UMAD_MAX_AGENTS;
193199
packet->mad.hdr.id++)
194200
if (agent == __get_agent(file, packet->mad.hdr.id)) {
195201
list_add_tail(&packet->list, &file->recv_list);
202+
atomic_inc(&file->recv_list_size);
196203
wake_up_interruptible(&file->recv_wait);
197204
ret = 0;
198205
break;
199206
}
200-
207+
unlock:
201208
mutex_unlock(&file->mutex);
202209

203210
return ret;
@@ -224,7 +231,7 @@ static void send_handler(struct ib_mad_agent *agent,
224231
if (send_wc->status == IB_WC_RESP_TIMEOUT_ERR) {
225232
packet->length = IB_MGMT_MAD_HDR;
226233
packet->mad.hdr.status = ETIMEDOUT;
227-
if (!queue_packet(file, agent, packet))
234+
if (!queue_packet(file, agent, packet, false))
228235
return;
229236
}
230237
kfree(packet);
@@ -284,7 +291,7 @@ static void recv_handler(struct ib_mad_agent *agent,
284291
rdma_destroy_ah_attr(&ah_attr);
285292
}
286293

287-
if (queue_packet(file, agent, packet))
294+
if (queue_packet(file, agent, packet, true))
288295
goto err2;
289296
return;
290297

@@ -409,6 +416,7 @@ static ssize_t ib_umad_read(struct file *filp, char __user *buf,
409416

410417
packet = list_entry(file->recv_list.next, struct ib_umad_packet, list);
411418
list_del(&packet->list);
419+
atomic_dec(&file->recv_list_size);
412420

413421
mutex_unlock(&file->mutex);
414422

@@ -421,6 +429,7 @@ static ssize_t ib_umad_read(struct file *filp, char __user *buf,
421429
/* Requeue packet */
422430
mutex_lock(&file->mutex);
423431
list_add(&packet->list, &file->recv_list);
432+
atomic_inc(&file->recv_list_size);
424433
mutex_unlock(&file->mutex);
425434
} else {
426435
if (packet->recv_wc)

0 commit comments

Comments
 (0)