linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Rasmus Villemoes <rasmus.villemoes@prevas.dk>
To: Li Yang <leoyang.li@nxp.com>,
	"David S. Miller" <davem@davemloft.net>,
	Jakub Kicinski <kuba@kernel.org>
Cc: Zhao Qiang <qiang.zhao@nxp.com>,
	Vladimir Oltean <vladimir.oltean@nxp.com>,
	Rasmus Villemoes <rasmus.villemoes@prevas.dk>,
	netdev@vger.kernel.org, linuxppc-dev@lists.ozlabs.org,
	linux-kernel@vger.kernel.org
Subject: [PATCH 20/20] ethernet: ucc_geth: simplify rx/tx allocations
Date: Sat,  5 Dec 2020 20:17:43 +0100	[thread overview]
Message-ID: <20201205191744.7847-21-rasmus.villemoes@prevas.dk> (raw)
In-Reply-To: <20201205191744.7847-1-rasmus.villemoes@prevas.dk>

Since kmalloc() is nowadays [1] guaranteed to return naturally
aligned (i.e., aligned to the size itself) memory for power-of-2
sizes, we don't need to over-allocate the align amount, compute an
aligned address within the allocation, and (for later freeing) also
storing the original pointer [2].

Instead, just round up the length we want to allocate to the alignment
requirements, then round that up to the next power of 2. In theory,
this could allocate up to about twice as much memory as we needed.  In
practice, (a) kmalloc() would in most cases anyway return a
power-of-2-sized allocation and (b) with the default values of the
bdRingLen[RT]x fields, the length is already itself a power of 2
greater than the alignment.

So we actually end up saving memory compared to the current
situtation (e.g. for tx, we currently allocate 128+32 bytes, which
kmalloc() likely rounds up to 192 or 256; with this patch, we just
allocate 128 bytes.) Also struct ucc_geth_private becomes a little
smaller.

[1] 59bb47985c1d ("mm, sl[aou]b: guarantee natural alignment for
kmalloc(power-of-two)")

[2] That storing was anyway done in a u32, which works on 32 bit
machines, but is not very elegant and certainly makes a reader of the
code pause for a while.

Signed-off-by: Rasmus Villemoes <rasmus.villemoes@prevas.dk>
---
 drivers/net/ethernet/freescale/ucc_geth.c | 50 ++++++++---------------
 drivers/net/ethernet/freescale/ucc_geth.h |  2 -
 2 files changed, 17 insertions(+), 35 deletions(-)

diff --git a/drivers/net/ethernet/freescale/ucc_geth.c b/drivers/net/ethernet/freescale/ucc_geth.c
index 3cad2255bd97..a4ed9209513e 100644
--- a/drivers/net/ethernet/freescale/ucc_geth.c
+++ b/drivers/net/ethernet/freescale/ucc_geth.c
@@ -1835,7 +1835,7 @@ static void ucc_geth_free_rx(struct ucc_geth_private *ugeth)
 
 			kfree(ugeth->rx_skbuff[i]);
 
-			kfree((void *)ugeth->rx_bd_ring_offset[i]);
+			kfree(ugeth->p_rx_bd_ring[i]);
 			ugeth->p_rx_bd_ring[i] = NULL;
 		}
 	}
@@ -1872,10 +1872,8 @@ static void ucc_geth_free_tx(struct ucc_geth_private *ugeth)
 
 		kfree(ugeth->tx_skbuff[i]);
 
-		if (ugeth->p_tx_bd_ring[i]) {
-			kfree((void *)ugeth->tx_bd_ring_offset[i]);
-			ugeth->p_tx_bd_ring[i] = NULL;
-		}
+		kfree(ugeth->p_tx_bd_ring[i]);
+		ugeth->p_tx_bd_ring[i] = NULL;
 	}
 
 }
@@ -2150,25 +2148,15 @@ static int ucc_geth_alloc_tx(struct ucc_geth_private *ugeth)
 
 	/* Allocate Tx bds */
 	for (j = 0; j < ucc_geth_tx_queues(ug_info); j++) {
-		u32 align = UCC_GETH_TX_BD_RING_ALIGNMENT;
-
-		/* Allocate in multiple of
-		   UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT,
-		   according to spec */
-		length = ((ug_info->bdRingLenTx[j] * sizeof(struct qe_bd))
-			  / UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT)
-		    * UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT;
-		if ((ug_info->bdRingLenTx[j] * sizeof(struct qe_bd)) %
-		    UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT)
-			length += UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT;
-
-		ugeth->tx_bd_ring_offset[j] =
-			(u32) kmalloc((u32) (length + align), GFP_KERNEL);
-
-		if (ugeth->tx_bd_ring_offset[j] != 0)
-			ugeth->p_tx_bd_ring[j] =
-				(u8 __iomem *)((ugeth->tx_bd_ring_offset[j] +
-						align) & ~(align - 1));
+		u32 align = max(UCC_GETH_TX_BD_RING_ALIGNMENT,
+				UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT);
+		u32 alloc;
+
+		length = ug_info->bdRingLenTx[j] * sizeof(struct qe_bd);
+		alloc = round_up(length, align);
+		alloc = roundup_pow_of_two(alloc);
+
+		ugeth->p_tx_bd_ring[j] = kmalloc(alloc, GFP_KERNEL);
 
 		if (!ugeth->p_tx_bd_ring[j]) {
 			if (netif_msg_ifup(ugeth))
@@ -2176,9 +2164,7 @@ static int ucc_geth_alloc_tx(struct ucc_geth_private *ugeth)
 			return -ENOMEM;
 		}
 		/* Zero unused end of bd ring, according to spec */
-		memset_io((void __iomem *)(ugeth->p_tx_bd_ring[j] +
-		       ug_info->bdRingLenTx[j] * sizeof(struct qe_bd)), 0,
-		       length - ug_info->bdRingLenTx[j] * sizeof(struct qe_bd));
+		memset(ugeth->p_tx_bd_ring[j] + length, 0, alloc - length);
 	}
 
 	/* Init Tx bds */
@@ -2225,15 +2211,13 @@ static int ucc_geth_alloc_rx(struct ucc_geth_private *ugeth)
 	/* Allocate Rx bds */
 	for (j = 0; j < ucc_geth_rx_queues(ug_info); j++) {
 		u32 align = UCC_GETH_RX_BD_RING_ALIGNMENT;
+		u32 alloc;
 
 		length = ug_info->bdRingLenRx[j] * sizeof(struct qe_bd);
-		ugeth->rx_bd_ring_offset[j] =
-			(u32) kmalloc((u32) (length + align), GFP_KERNEL);
-		if (ugeth->rx_bd_ring_offset[j] != 0)
-			ugeth->p_rx_bd_ring[j] =
-				(u8 __iomem *)((ugeth->rx_bd_ring_offset[j] +
-						align) & ~(align - 1));
+		alloc = round_up(length, align);
+		alloc = roundup_pow_of_two(alloc);
 
+		ugeth->p_rx_bd_ring[j] = kmalloc(alloc, GFP_KERNEL);
 		if (!ugeth->p_rx_bd_ring[j]) {
 			if (netif_msg_ifup(ugeth))
 				pr_err("Can not allocate memory for Rx bd rings\n");
diff --git a/drivers/net/ethernet/freescale/ucc_geth.h b/drivers/net/ethernet/freescale/ucc_geth.h
index 6539fed9cc22..ccc4ca1ae9b6 100644
--- a/drivers/net/ethernet/freescale/ucc_geth.h
+++ b/drivers/net/ethernet/freescale/ucc_geth.h
@@ -1182,9 +1182,7 @@ struct ucc_geth_private {
 	struct ucc_geth_rx_bd_queues_entry __iomem *p_rx_bd_qs_tbl;
 	u32 rx_bd_qs_tbl_offset;
 	u8 __iomem *p_tx_bd_ring[NUM_TX_QUEUES];
-	u32 tx_bd_ring_offset[NUM_TX_QUEUES];
 	u8 __iomem *p_rx_bd_ring[NUM_RX_QUEUES];
-	u32 rx_bd_ring_offset[NUM_RX_QUEUES];
 	u8 __iomem *confBd[NUM_TX_QUEUES];
 	u8 __iomem *txBd[NUM_TX_QUEUES];
 	u8 __iomem *rxBd[NUM_RX_QUEUES];
-- 
2.23.0


  parent reply	other threads:[~2020-12-05 19:21 UTC|newest]

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-12-05 19:17 [PATCH 00/20] ethernet: ucc_geth: assorted fixes and simplifications Rasmus Villemoes
2020-12-05 19:17 ` [PATCH 01/20] ethernet: ucc_geth: set dev->max_mtu to 1518 Rasmus Villemoes
2020-12-10  1:25   ` Andrew Lunn
2021-01-05 14:17     ` Joakim Tjernlund
2021-01-05 14:33       ` Andrew Lunn
2021-01-05 14:44         ` Joakim Tjernlund
2021-01-05 14:54           ` Andrew Lunn
2020-12-05 19:17 ` [PATCH 02/20] ethernet: ucc_geth: fix definition and size of ucc_geth_tx_global_pram Rasmus Villemoes
2020-12-08 19:14   ` Li Yang
2020-12-08 20:12     ` Rasmus Villemoes
2020-12-05 19:17 ` [PATCH 03/20] ethernet: ucc_geth: remove unused read of temoder field Rasmus Villemoes
2020-12-05 19:17 ` [PATCH 04/20] soc: fsl: qe: make cpm_muram_offset take a const void* argument Rasmus Villemoes
2020-12-05 19:17 ` [PATCH 05/20] soc: fsl: qe: store muram_vbase as a void pointer instead of u8 Rasmus Villemoes
2020-12-05 19:17 ` [PATCH 06/20] soc: fsl: qe: add cpm_muram_free_addr() helper Rasmus Villemoes
2020-12-05 19:17 ` [PATCH 07/20] ethernet: ucc_geth: use qe_muram_free_addr() Rasmus Villemoes
2020-12-10  1:36   ` Andrew Lunn
2020-12-05 19:17 ` [PATCH 08/20] ethernet: ucc_geth: remove unnecessary memset_io() calls Rasmus Villemoes
2020-12-05 19:17 ` [PATCH 09/20] ethernet: ucc_geth: replace kmalloc+memset by kzalloc Rasmus Villemoes
2020-12-05 19:17 ` [PATCH 10/20] ethernet: ucc_geth: remove {rx,tx}_glbl_pram_offset from struct ucc_geth_private Rasmus Villemoes
2020-12-05 19:17 ` [PATCH 11/20] ethernet: ucc_geth: fix use-after-free in ucc_geth_remove() Rasmus Villemoes
2020-12-05 20:48   ` Jakub Kicinski
2020-12-05 21:04     ` Rasmus Villemoes
2020-12-05 21:19       ` Jakub Kicinski
2020-12-05 21:35         ` Rasmus Villemoes
2020-12-05 21:50       ` Rasmus Villemoes
2020-12-05 19:17 ` [PATCH 12/20] ethernet: ucc_geth: factor out parsing of {rx,tx}-clock{,-name} properties Rasmus Villemoes
2020-12-05 19:17 ` [PATCH 13/20] ethernet: ucc_geth: constify ugeth_primary_info Rasmus Villemoes
2020-12-05 19:17 ` [PATCH 14/20] ethernet: ucc_geth: don't statically allocate eight ucc_geth_info Rasmus Villemoes
2020-12-08 15:13   ` Christophe Leroy
2020-12-08 21:17     ` Rasmus Villemoes
2020-12-05 19:17 ` [PATCH 15/20] ethernet: ucc_geth: use UCC_GETH_{RX,TX}_BD_RING_ALIGNMENT macros directly Rasmus Villemoes
2020-12-08 15:14   ` [PATCH 15/20] ethernet: ucc_geth: use UCC_GETH_{RX, TX}_BD_RING_ALIGNMENT " Christophe Leroy
2020-12-05 19:17 ` [PATCH 16/20] ethernet: ucc_geth: remove bd_mem_part and all associated code Rasmus Villemoes
2020-12-05 19:17 ` [PATCH 17/20] ethernet: ucc_geth: replace kmalloc_array()+for loop by kcalloc() Rasmus Villemoes
2020-12-05 19:17 ` [PATCH 18/20] ethernet: ucc_geth: add helper to replace repeated switch statements Rasmus Villemoes
2020-12-08 15:21   ` Christophe Leroy
2020-12-08 20:55     ` Rasmus Villemoes
2020-12-05 19:17 ` [PATCH 19/20] ethernet: ucc_geth: inform the compiler that numQueues is always 1 Rasmus Villemoes
2020-12-05 19:17 ` Rasmus Villemoes [this message]
2020-12-05 20:53 ` [PATCH 00/20] ethernet: ucc_geth: assorted fixes and simplifications Jakub Kicinski
2020-12-05 21:11   ` Rasmus Villemoes
2020-12-05 21:27     ` Jakub Kicinski
2020-12-05 21:36       ` Rasmus Villemoes
2020-12-10  7:52       ` Rasmus Villemoes
2020-12-08  3:07     ` Qiang Zhao
2020-12-08  8:13       ` Rasmus Villemoes

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20201205191744.7847-21-rasmus.villemoes@prevas.dk \
    --to=rasmus.villemoes@prevas.dk \
    --cc=davem@davemloft.net \
    --cc=kuba@kernel.org \
    --cc=leoyang.li@nxp.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linuxppc-dev@lists.ozlabs.org \
    --cc=netdev@vger.kernel.org \
    --cc=qiang.zhao@nxp.com \
    --cc=vladimir.oltean@nxp.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).