| From ea116dd81d667a4964e891f47de7aabf4f33b477 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Mon, 29 Mar 2021 09:54:09 -0400 |
| Subject: IB/hfi1: Correct oversized ring allocation |
| |
| From: Mike Marciniszyn <mike.marciniszyn@cornelisnetworks.com> |
| |
| [ Upstream commit b536d4b2a279733f440c911dc831764690b90050 ] |
| |
| The completion ring for tx is using the wrong size to size the ring, |
| oversizing the ring by two orders of magniture. |
| |
| Correct the allocation size and use kcalloc_node() to allocate the ring. |
| Fix mistaken GFP defines in similar allocations. |
| |
| Link: https://lore.kernel.org/r/1617026056-50483-4-git-send-email-dennis.dalessandro@cornelisnetworks.com |
| Reviewed-by: Kaike Wan <kaike.wan@intel.com> |
| Signed-off-by: Mike Marciniszyn <mike.marciniszyn@cornelisnetworks.com> |
| Signed-off-by: Dennis Dalessandro <dennis.dalessandro@cornelisnetworks.com> |
| Signed-off-by: Jason Gunthorpe <jgg@nvidia.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/infiniband/hw/hfi1/ipoib.h | 3 ++- |
| drivers/infiniband/hw/hfi1/ipoib_tx.c | 14 +++++++------- |
| 2 files changed, 9 insertions(+), 8 deletions(-) |
| |
| diff --git a/drivers/infiniband/hw/hfi1/ipoib.h b/drivers/infiniband/hw/hfi1/ipoib.h |
| index b8c9d0a003fb..1ee361c6d11a 100644 |
| --- a/drivers/infiniband/hw/hfi1/ipoib.h |
| +++ b/drivers/infiniband/hw/hfi1/ipoib.h |
| @@ -52,8 +52,9 @@ union hfi1_ipoib_flow { |
| * @producer_lock: producer sync lock |
| * @consumer_lock: consumer sync lock |
| */ |
| +struct ipoib_txreq; |
| struct hfi1_ipoib_circ_buf { |
| - void **items; |
| + struct ipoib_txreq **items; |
| unsigned long head; |
| unsigned long tail; |
| unsigned long max_items; |
| diff --git a/drivers/infiniband/hw/hfi1/ipoib_tx.c b/drivers/infiniband/hw/hfi1/ipoib_tx.c |
| index 9df292b51a05..ab1eefffc14b 100644 |
| --- a/drivers/infiniband/hw/hfi1/ipoib_tx.c |
| +++ b/drivers/infiniband/hw/hfi1/ipoib_tx.c |
| @@ -702,14 +702,14 @@ int hfi1_ipoib_txreq_init(struct hfi1_ipoib_dev_priv *priv) |
| |
| priv->tx_napis = kcalloc_node(dev->num_tx_queues, |
| sizeof(struct napi_struct), |
| - GFP_ATOMIC, |
| + GFP_KERNEL, |
| priv->dd->node); |
| if (!priv->tx_napis) |
| goto free_txreq_cache; |
| |
| priv->txqs = kcalloc_node(dev->num_tx_queues, |
| sizeof(struct hfi1_ipoib_txq), |
| - GFP_ATOMIC, |
| + GFP_KERNEL, |
| priv->dd->node); |
| if (!priv->txqs) |
| goto free_tx_napis; |
| @@ -741,9 +741,9 @@ int hfi1_ipoib_txreq_init(struct hfi1_ipoib_dev_priv *priv) |
| priv->dd->node); |
| |
| txq->tx_ring.items = |
| - vzalloc_node(array_size(tx_ring_size, |
| - sizeof(struct ipoib_txreq)), |
| - priv->dd->node); |
| + kcalloc_node(tx_ring_size, |
| + sizeof(struct ipoib_txreq *), |
| + GFP_KERNEL, priv->dd->node); |
| if (!txq->tx_ring.items) |
| goto free_txqs; |
| |
| @@ -764,7 +764,7 @@ free_txqs: |
| struct hfi1_ipoib_txq *txq = &priv->txqs[i]; |
| |
| netif_napi_del(txq->napi); |
| - vfree(txq->tx_ring.items); |
| + kfree(txq->tx_ring.items); |
| } |
| |
| kfree(priv->txqs); |
| @@ -817,7 +817,7 @@ void hfi1_ipoib_txreq_deinit(struct hfi1_ipoib_dev_priv *priv) |
| hfi1_ipoib_drain_tx_list(txq); |
| netif_napi_del(txq->napi); |
| (void)hfi1_ipoib_drain_tx_ring(txq, txq->tx_ring.max_items); |
| - vfree(txq->tx_ring.items); |
| + kfree(txq->tx_ring.items); |
| } |
| |
| kfree(priv->txqs); |
| -- |
| 2.30.2 |
| |