From patchwork Tue Apr 16 12:01:44 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Leon Romanovsky X-Patchwork-Id: 13631734 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 16615129A7C for ; Tue, 16 Apr 2024 12:01:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713268912; cv=none; b=VTE+RVY3T/X8EqTsvugcRmKECm5PgBM+cT1KrjaLTKnAgr9untoXHS2tY+D58WKjA/pcxlAY+qHA05wiIUOrJTlpZWBHexXh/q6HHsD8TPGDR9R0chyDd4N/IAxKTCzHn4Q+w0ApjomobthhqpNNWlM8wMxXq2JB+KDN1s/z2II= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713268912; c=relaxed/simple; bh=Xh+479ngd4H0PXlh6k6him+/1ZmzfcsAq0aZr7ehGs4=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=mBsjwj9c+MtUjEkYr/hPa0R7GnC+g5T+O2MwljXQea2Yvfa158gq7gzY2fafwIWkfNV9YrvUW0VYPRem4pIrIxhoyun2a+cHbbffgQF9nuENXP63Fk4GkMWr7b/8z7e1GR1XtnNN+Pdym0Qz2ZF4XZ0aE0hNf5FBrRSUY8N9GDQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=pUN3Ddfg; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="pUN3Ddfg" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0636AC2BD10; Tue, 16 Apr 2024 12:01:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1713268911; bh=Xh+479ngd4H0PXlh6k6him+/1ZmzfcsAq0aZr7ehGs4=; h=From:To:Cc:Subject:Date:From; b=pUN3DdfghzCIEQ6hSnxdGf0b6h4udBMMhXkGdCvaSylKKH09COpiY19hDU+f23sah mQ/0IjNEVmwTb/r2JkQwqwUN4Tjzxt6Raqw8GAjwPN3XajeyOITYw38kDENl0ah3aJ MXG5lOEfCT4VE1h4HNNE7L69VgAh+cmwWjw94OsvbQTGsrH+P1MdkvDvmEzyPOJY5l 2sk9BupzKdsZcksJvXwouAstYEeUW1ctinjkjWMUZ9cnWL79N2lCYjP25i8l1bRO/O Qu9XSk+/zeTBqazrVh1WDUq4q/4wsdGE6Usv7nuvaS2H6Kq6soFCpfTIgW3WOv6fxr chdosoQ+sDWNQ== From: Leon Romanovsky To: Jason Gunthorpe Cc: Michael Guralnik , linux-rdma@vger.kernel.org, Mark Zhang Subject: [PATCH rdma-next v2] IB/core: Implement a limit on UMAD receive List Date: Tue, 16 Apr 2024 15:01:44 +0300 Message-ID: <7197cb58a7d9e78399008f25036205ceab07fbd5.1713268818.git.leon@kernel.org> X-Mailer: git-send-email 2.44.0 Precedence: bulk X-Mailing-List: linux-rdma@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Michael Guralnik 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 Reviewed-by: Mark Zhang Signed-off-by: Leon Romanovsky --- Changelog: v2: * Fixed condition v1: https://lore.kernel.org/all/e2262f827f43518e5e3a4d825a3e0514c0f7aa5f.1712668708.git.leonro@nvidia.com * Changed sysfs entry to hard coded value. * Rewrote the commit message. v0: https://lore.kernel.org/all/70029b5f256fbad6efbb98458deb9c46baa2c4b3.1712051390.git.leon@kernel.org --- drivers/infiniband/core/user_mad.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c index f5feca7fa9b9..2ed749f50a29 100644 --- a/drivers/infiniband/core/user_mad.c +++ b/drivers/infiniband/core/user_mad.c @@ -63,6 +63,8 @@ MODULE_AUTHOR("Roland Dreier"); MODULE_DESCRIPTION("InfiniBand userspace MAD packet access"); MODULE_LICENSE("Dual BSD/GPL"); +#define MAX_UMAD_RECV_LIST_SIZE 200000 + enum { IB_UMAD_MAX_PORTS = RDMA_MAX_PORTS, IB_UMAD_MAX_AGENTS = 32, @@ -113,6 +115,7 @@ struct ib_umad_file { struct mutex mutex; struct ib_umad_port *port; struct list_head recv_list; + atomic_t recv_list_size; struct list_head send_list; struct list_head port_list; spinlock_t send_lock; @@ -180,24 +183,28 @@ static struct ib_mad_agent *__get_agent(struct ib_umad_file *file, int id) return file->agents_dead ? NULL : file->agent[id]; } -static int queue_packet(struct ib_umad_file *file, - struct ib_mad_agent *agent, - struct ib_umad_packet *packet) +static int queue_packet(struct ib_umad_file *file, struct ib_mad_agent *agent, + struct ib_umad_packet *packet, bool is_recv_mad) { int ret = 1; mutex_lock(&file->mutex); + if (is_recv_mad && + atomic_read(&file->recv_list_size) > MAX_UMAD_RECV_LIST_SIZE) + goto unlock; + for (packet->mad.hdr.id = 0; packet->mad.hdr.id < IB_UMAD_MAX_AGENTS; packet->mad.hdr.id++) if (agent == __get_agent(file, packet->mad.hdr.id)) { list_add_tail(&packet->list, &file->recv_list); + atomic_inc(&file->recv_list_size); wake_up_interruptible(&file->recv_wait); ret = 0; break; } - +unlock: mutex_unlock(&file->mutex); return ret; @@ -224,7 +231,7 @@ static void send_handler(struct ib_mad_agent *agent, if (send_wc->status == IB_WC_RESP_TIMEOUT_ERR) { packet->length = IB_MGMT_MAD_HDR; packet->mad.hdr.status = ETIMEDOUT; - if (!queue_packet(file, agent, packet)) + if (!queue_packet(file, agent, packet, false)) return; } kfree(packet); @@ -284,7 +291,7 @@ static void recv_handler(struct ib_mad_agent *agent, rdma_destroy_ah_attr(&ah_attr); } - if (queue_packet(file, agent, packet)) + if (queue_packet(file, agent, packet, true)) goto err2; return; @@ -409,6 +416,7 @@ static ssize_t ib_umad_read(struct file *filp, char __user *buf, packet = list_entry(file->recv_list.next, struct ib_umad_packet, list); list_del(&packet->list); + atomic_dec(&file->recv_list_size); mutex_unlock(&file->mutex); @@ -421,6 +429,7 @@ static ssize_t ib_umad_read(struct file *filp, char __user *buf, /* Requeue packet */ mutex_lock(&file->mutex); list_add(&packet->list, &file->recv_list); + atomic_inc(&file->recv_list_size); mutex_unlock(&file->mutex); } else { if (packet->recv_wc)