* [PATCH 10/20] ethernet: ucc_geth: remove {rx, tx}_glbl_pram_offset from struct ucc_geth_private
From: Rasmus Villemoes @ 2020-12-05 19:17 UTC (permalink / raw)
To: Li Yang, David S. Miller, Jakub Kicinski
Cc: Rasmus Villemoes, Vladimir Oltean, linux-kernel, netdev,
linuxppc-dev, Zhao Qiang
In-Reply-To: <20201205191744.7847-1-rasmus.villemoes@prevas.dk>
These fields are only used within ucc_geth_startup(), so they might as
well be local variables in that function rather than being stashed in
struct ucc_geth_private.
Aside from making that struct a tiny bit smaller, it also shortens
some lines (getting rid of pointless casts while here), and fixes the
problems with using IS_ERR_VALUE() on a u32 as explained in commit
800cd6fb76f0 ("soc: fsl: qe: change return type of cpm_muram_alloc()
to s32").
Signed-off-by: Rasmus Villemoes <rasmus.villemoes@prevas.dk>
---
drivers/net/ethernet/freescale/ucc_geth.c | 21 +++++++++------------
drivers/net/ethernet/freescale/ucc_geth.h | 2 --
2 files changed, 9 insertions(+), 14 deletions(-)
diff --git a/drivers/net/ethernet/freescale/ucc_geth.c b/drivers/net/ethernet/freescale/ucc_geth.c
index e1574c14b7e5..b132fcfc7c17 100644
--- a/drivers/net/ethernet/freescale/ucc_geth.c
+++ b/drivers/net/ethernet/freescale/ucc_geth.c
@@ -2351,6 +2351,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
u8 function_code = 0;
u8 __iomem *endOfRing;
u8 numThreadsRxNumerical, numThreadsTxNumerical;
+ s32 rx_glbl_pram_offset, tx_glbl_pram_offset;
ugeth_vdbg("%s: IN", __func__);
uccf = ugeth->uccf;
@@ -2495,17 +2496,15 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
*/
/* Tx global PRAM */
/* Allocate global tx parameter RAM page */
- ugeth->tx_glbl_pram_offset =
+ tx_glbl_pram_offset =
qe_muram_alloc(sizeof(struct ucc_geth_tx_global_pram),
UCC_GETH_TX_GLOBAL_PRAM_ALIGNMENT);
- if (IS_ERR_VALUE(ugeth->tx_glbl_pram_offset)) {
+ if (tx_glbl_pram_offset < 0) {
if (netif_msg_ifup(ugeth))
pr_err("Can not allocate DPRAM memory for p_tx_glbl_pram\n");
return -ENOMEM;
}
- ugeth->p_tx_glbl_pram =
- (struct ucc_geth_tx_global_pram __iomem *) qe_muram_addr(ugeth->
- tx_glbl_pram_offset);
+ ugeth->p_tx_glbl_pram = qe_muram_addr(tx_glbl_pram_offset);
/* Fill global PRAM */
/* TQPTR */
@@ -2656,17 +2655,15 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
/* Rx global PRAM */
/* Allocate global rx parameter RAM page */
- ugeth->rx_glbl_pram_offset =
+ rx_glbl_pram_offset =
qe_muram_alloc(sizeof(struct ucc_geth_rx_global_pram),
UCC_GETH_RX_GLOBAL_PRAM_ALIGNMENT);
- if (IS_ERR_VALUE(ugeth->rx_glbl_pram_offset)) {
+ if (rx_glbl_pram_offset < 0) {
if (netif_msg_ifup(ugeth))
pr_err("Can not allocate DPRAM memory for p_rx_glbl_pram\n");
return -ENOMEM;
}
- ugeth->p_rx_glbl_pram =
- (struct ucc_geth_rx_global_pram __iomem *) qe_muram_addr(ugeth->
- rx_glbl_pram_offset);
+ ugeth->p_rx_glbl_pram = qe_muram_addr(rx_glbl_pram_offset);
/* Fill global PRAM */
/* RQPTR */
@@ -2928,7 +2925,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
((u32) ug_info->numThreadsTx) << ENET_INIT_PARAM_TGF_SHIFT;
ugeth->p_init_enet_param_shadow->rgftgfrxglobal |=
- ugeth->rx_glbl_pram_offset | ug_info->riscRx;
+ rx_glbl_pram_offset | ug_info->riscRx;
if ((ug_info->largestexternallookupkeysize !=
QE_FLTR_LARGEST_EXTERNAL_TABLE_LOOKUP_KEY_SIZE_NONE) &&
(ug_info->largestexternallookupkeysize !=
@@ -2966,7 +2963,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
}
ugeth->p_init_enet_param_shadow->txglobal =
- ugeth->tx_glbl_pram_offset | ug_info->riscTx;
+ tx_glbl_pram_offset | ug_info->riscTx;
if ((ret_val =
fill_init_enet_entries(ugeth,
&(ugeth->p_init_enet_param_shadow->
diff --git a/drivers/net/ethernet/freescale/ucc_geth.h b/drivers/net/ethernet/freescale/ucc_geth.h
index c80bed2c995c..be47fa8ced15 100644
--- a/drivers/net/ethernet/freescale/ucc_geth.h
+++ b/drivers/net/ethernet/freescale/ucc_geth.h
@@ -1166,9 +1166,7 @@ struct ucc_geth_private {
struct ucc_geth_exf_global_pram __iomem *p_exf_glbl_param;
u32 exf_glbl_param_offset;
struct ucc_geth_rx_global_pram __iomem *p_rx_glbl_pram;
- u32 rx_glbl_pram_offset;
struct ucc_geth_tx_global_pram __iomem *p_tx_glbl_pram;
- u32 tx_glbl_pram_offset;
struct ucc_geth_send_queue_mem_region __iomem *p_send_q_mem_reg;
u32 send_q_mem_reg_offset;
struct ucc_geth_thread_data_tx __iomem *p_thread_data_tx;
--
2.23.0
^ permalink raw reply related
* [PATCH 12/20] ethernet: ucc_geth: factor out parsing of {rx, tx}-clock{, -name} properties
From: Rasmus Villemoes @ 2020-12-05 19:17 UTC (permalink / raw)
To: Li Yang, David S. Miller, Jakub Kicinski
Cc: Rasmus Villemoes, Vladimir Oltean, linux-kernel, netdev,
linuxppc-dev, Zhao Qiang
In-Reply-To: <20201205191744.7847-1-rasmus.villemoes@prevas.dk>
Reduce the code duplication a bit by moving the parsing of
rx-clock-name and the fallback handling to a helper function.
Signed-off-by: Rasmus Villemoes <rasmus.villemoes@prevas.dk>
---
drivers/net/ethernet/freescale/ucc_geth.c | 79 ++++++++++-------------
1 file changed, 35 insertions(+), 44 deletions(-)
diff --git a/drivers/net/ethernet/freescale/ucc_geth.c b/drivers/net/ethernet/freescale/ucc_geth.c
index ba911d05d36d..700eafef4921 100644
--- a/drivers/net/ethernet/freescale/ucc_geth.c
+++ b/drivers/net/ethernet/freescale/ucc_geth.c
@@ -3646,6 +3646,35 @@ static const struct net_device_ops ucc_geth_netdev_ops = {
#endif
};
+static int ucc_geth_parse_clock(struct device_node *np, const char *which,
+ enum qe_clock *out)
+{
+ const char *sprop;
+ char buf[24];
+
+ snprintf(buf, sizeof(buf), "%s-clock-name", which);
+ sprop = of_get_property(np, buf, NULL);
+ if (sprop) {
+ *out = qe_clock_source(sprop);
+ } else {
+ u32 val;
+
+ snprintf(buf, sizeof(buf), "%s-clock", which);
+ if (of_property_read_u32(np, buf, &val)) {
+ /* If both *-clock-name and *-clock are missing,
+ we want to tell people to use *-clock-name. */
+ pr_err("missing %s-name property\n", buf);
+ return -EINVAL;
+ }
+ *out = val;
+ }
+ if (*out < QE_CLK_NONE || *out > QE_CLK24) {
+ pr_err("invalid %s property\n", buf);
+ return -EINVAL;
+ }
+ return 0;
+}
+
static int ucc_geth_probe(struct platform_device* ofdev)
{
struct device *device = &ofdev->dev;
@@ -3656,7 +3685,6 @@ static int ucc_geth_probe(struct platform_device* ofdev)
struct resource res;
int err, ucc_num, max_speed = 0;
const unsigned int *prop;
- const char *sprop;
const void *mac_addr;
phy_interface_t phy_interface;
static const int enet_to_speed[] = {
@@ -3695,49 +3723,12 @@ static int ucc_geth_probe(struct platform_device* ofdev)
ug_info->uf_info.ucc_num = ucc_num;
- sprop = of_get_property(np, "rx-clock-name", NULL);
- if (sprop) {
- ug_info->uf_info.rx_clock = qe_clock_source(sprop);
- if ((ug_info->uf_info.rx_clock < QE_CLK_NONE) ||
- (ug_info->uf_info.rx_clock > QE_CLK24)) {
- pr_err("invalid rx-clock-name property\n");
- return -EINVAL;
- }
- } else {
- prop = of_get_property(np, "rx-clock", NULL);
- if (!prop) {
- /* If both rx-clock-name and rx-clock are missing,
- we want to tell people to use rx-clock-name. */
- pr_err("missing rx-clock-name property\n");
- return -EINVAL;
- }
- if ((*prop < QE_CLK_NONE) || (*prop > QE_CLK24)) {
- pr_err("invalid rx-clock property\n");
- return -EINVAL;
- }
- ug_info->uf_info.rx_clock = *prop;
- }
-
- sprop = of_get_property(np, "tx-clock-name", NULL);
- if (sprop) {
- ug_info->uf_info.tx_clock = qe_clock_source(sprop);
- if ((ug_info->uf_info.tx_clock < QE_CLK_NONE) ||
- (ug_info->uf_info.tx_clock > QE_CLK24)) {
- pr_err("invalid tx-clock-name property\n");
- return -EINVAL;
- }
- } else {
- prop = of_get_property(np, "tx-clock", NULL);
- if (!prop) {
- pr_err("missing tx-clock-name property\n");
- return -EINVAL;
- }
- if ((*prop < QE_CLK_NONE) || (*prop > QE_CLK24)) {
- pr_err("invalid tx-clock property\n");
- return -EINVAL;
- }
- ug_info->uf_info.tx_clock = *prop;
- }
+ err = ucc_geth_parse_clock(np, "rx", &ug_info->uf_info.rx_clock);
+ if (err)
+ return err;
+ err = ucc_geth_parse_clock(np, "tx", &ug_info->uf_info.tx_clock);
+ if (err)
+ return err;
err = of_address_to_resource(np, 0, &res);
if (err)
--
2.23.0
^ permalink raw reply related
* [PATCH 11/20] ethernet: ucc_geth: fix use-after-free in ucc_geth_remove()
From: Rasmus Villemoes @ 2020-12-05 19:17 UTC (permalink / raw)
To: Li Yang, David S. Miller, Jakub Kicinski
Cc: Rasmus Villemoes, Vladimir Oltean, linux-kernel, netdev,
linuxppc-dev, Zhao Qiang
In-Reply-To: <20201205191744.7847-1-rasmus.villemoes@prevas.dk>
ugeth is the netdiv_priv() part of the netdevice. Accessing the memory
pointed to by ugeth (such as done by ucc_geth_memclean() and the two
of_node_puts) after free_netdev() is thus use-after-free.
Signed-off-by: Rasmus Villemoes <rasmus.villemoes@prevas.dk>
---
drivers/net/ethernet/freescale/ucc_geth.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/freescale/ucc_geth.c b/drivers/net/ethernet/freescale/ucc_geth.c
index b132fcfc7c17..ba911d05d36d 100644
--- a/drivers/net/ethernet/freescale/ucc_geth.c
+++ b/drivers/net/ethernet/freescale/ucc_geth.c
@@ -3895,13 +3895,13 @@ static int ucc_geth_remove(struct platform_device* ofdev)
struct ucc_geth_private *ugeth = netdev_priv(dev);
struct device_node *np = ofdev->dev.of_node;
- unregister_netdev(dev);
- free_netdev(dev);
ucc_geth_memclean(ugeth);
if (of_phy_is_fixed_link(np))
of_phy_deregister_fixed_link(np);
of_node_put(ugeth->ug_info->tbi_node);
of_node_put(ugeth->ug_info->phy_node);
+ unregister_netdev(dev);
+ free_netdev(dev);
return 0;
}
--
2.23.0
^ permalink raw reply related
* [PATCH 13/20] ethernet: ucc_geth: constify ugeth_primary_info
From: Rasmus Villemoes @ 2020-12-05 19:17 UTC (permalink / raw)
To: Li Yang, David S. Miller, Jakub Kicinski
Cc: Rasmus Villemoes, Vladimir Oltean, linux-kernel, netdev,
linuxppc-dev, Zhao Qiang
In-Reply-To: <20201205191744.7847-1-rasmus.villemoes@prevas.dk>
Signed-off-by: Rasmus Villemoes <rasmus.villemoes@prevas.dk>
---
drivers/net/ethernet/freescale/ucc_geth.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/freescale/ucc_geth.c b/drivers/net/ethernet/freescale/ucc_geth.c
index 700eafef4921..a06744d8b4af 100644
--- a/drivers/net/ethernet/freescale/ucc_geth.c
+++ b/drivers/net/ethernet/freescale/ucc_geth.c
@@ -70,7 +70,7 @@ static struct {
module_param_named(debug, debug.msg_enable, int, 0);
MODULE_PARM_DESC(debug, "Debug verbosity level (0=none, ..., 0xffff=all)");
-static struct ucc_geth_info ugeth_primary_info = {
+static const struct ucc_geth_info ugeth_primary_info = {
.uf_info = {
.bd_mem_part = MEM_PART_SYSTEM,
.rtsm = UCC_FAST_SEND_IDLES_BETWEEN_FRAMES,
--
2.23.0
^ permalink raw reply related
* [PATCH 14/20] ethernet: ucc_geth: don't statically allocate eight ucc_geth_info
From: Rasmus Villemoes @ 2020-12-05 19:17 UTC (permalink / raw)
To: Li Yang, David S. Miller, Jakub Kicinski
Cc: Rasmus Villemoes, Vladimir Oltean, linux-kernel, netdev,
linuxppc-dev, Zhao Qiang
In-Reply-To: <20201205191744.7847-1-rasmus.villemoes@prevas.dk>
struct ucc_geth_info is somewhat large, and on systems with only one
or two UCC instances, that just wastes a few KB of memory. So
allocate and populate a chunk of memory at probe time instead of
initializing them all during driver init.
Note that the existing "ug_info == NULL" check was dead code, as the
address of some static array element can obviously never be NULL.
Signed-off-by: Rasmus Villemoes <rasmus.villemoes@prevas.dk>
---
drivers/net/ethernet/freescale/ucc_geth.c | 32 +++++++++--------------
1 file changed, 12 insertions(+), 20 deletions(-)
diff --git a/drivers/net/ethernet/freescale/ucc_geth.c b/drivers/net/ethernet/freescale/ucc_geth.c
index a06744d8b4af..273342233bba 100644
--- a/drivers/net/ethernet/freescale/ucc_geth.c
+++ b/drivers/net/ethernet/freescale/ucc_geth.c
@@ -157,8 +157,6 @@ static const struct ucc_geth_info ugeth_primary_info = {
.riscRx = QE_RISC_ALLOCATION_RISC1_AND_RISC2,
};
-static struct ucc_geth_info ugeth_info[8];
-
#ifdef DEBUG
static void mem_disp(u8 *addr, int size)
{
@@ -3714,25 +3712,23 @@ static int ucc_geth_probe(struct platform_device* ofdev)
if ((ucc_num < 0) || (ucc_num > 7))
return -ENODEV;
- ug_info = &ugeth_info[ucc_num];
- if (ug_info == NULL) {
- if (netif_msg_probe(&debug))
- pr_err("[%d] Missing additional data!\n", ucc_num);
- return -ENODEV;
- }
+ ug_info = kmalloc(sizeof(*ug_info), GFP_KERNEL);
+ if (ug_info == NULL)
+ return -ENOMEM;
+ memcpy(ug_info, &ugeth_primary_info, sizeof(*ug_info));
ug_info->uf_info.ucc_num = ucc_num;
err = ucc_geth_parse_clock(np, "rx", &ug_info->uf_info.rx_clock);
if (err)
- return err;
+ goto err_free_info;
err = ucc_geth_parse_clock(np, "tx", &ug_info->uf_info.tx_clock);
if (err)
- return err;
+ goto err_free_info;
err = of_address_to_resource(np, 0, &res);
if (err)
- return -EINVAL;
+ goto err_free_info;
ug_info->uf_info.regs = res.start;
ug_info->uf_info.irq = irq_of_parse_and_map(np, 0);
@@ -3745,7 +3741,7 @@ static int ucc_geth_probe(struct platform_device* ofdev)
*/
err = of_phy_register_fixed_link(np);
if (err)
- return err;
+ goto err_free_info;
ug_info->phy_node = of_node_get(np);
}
@@ -3876,6 +3872,8 @@ static int ucc_geth_probe(struct platform_device* ofdev)
of_phy_deregister_fixed_link(np);
of_node_put(ug_info->tbi_node);
of_node_put(ug_info->phy_node);
+err_free_info:
+ kfree(ug_info);
return err;
}
@@ -3886,6 +3884,7 @@ static int ucc_geth_remove(struct platform_device* ofdev)
struct ucc_geth_private *ugeth = netdev_priv(dev);
struct device_node *np = ofdev->dev.of_node;
+ kfree(ugeth->ug_info);
ucc_geth_memclean(ugeth);
if (of_phy_is_fixed_link(np))
of_phy_deregister_fixed_link(np);
@@ -3920,17 +3919,10 @@ static struct platform_driver ucc_geth_driver = {
static int __init ucc_geth_init(void)
{
- int i, ret;
-
if (netif_msg_drv(&debug))
pr_info(DRV_DESC "\n");
- for (i = 0; i < 8; i++)
- memcpy(&(ugeth_info[i]), &ugeth_primary_info,
- sizeof(ugeth_primary_info));
-
- ret = platform_driver_register(&ucc_geth_driver);
- return ret;
+ return platform_driver_register(&ucc_geth_driver);
}
static void __exit ucc_geth_exit(void)
--
2.23.0
^ permalink raw reply related
* [PATCH 15/20] ethernet: ucc_geth: use UCC_GETH_{RX, TX}_BD_RING_ALIGNMENT macros directly
From: Rasmus Villemoes @ 2020-12-05 19:17 UTC (permalink / raw)
To: Li Yang, David S. Miller, Jakub Kicinski
Cc: Rasmus Villemoes, Vladimir Oltean, linux-kernel, netdev,
linuxppc-dev, Zhao Qiang
In-Reply-To: <20201205191744.7847-1-rasmus.villemoes@prevas.dk>
These macros both have the value 32, there's no point first
initializing align to a lower value.
If anything, one could throw in a
BUILD_BUG_ON(UCC_GETH_TX_BD_RING_ALIGNMENT < 4), but it's not worth it
- lots of code depends on named constants having sensible values.
Signed-off-by: Rasmus Villemoes <rasmus.villemoes@prevas.dk>
---
drivers/net/ethernet/freescale/ucc_geth.c | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/freescale/ucc_geth.c b/drivers/net/ethernet/freescale/ucc_geth.c
index 273342233bba..ccde42f547b8 100644
--- a/drivers/net/ethernet/freescale/ucc_geth.c
+++ b/drivers/net/ethernet/freescale/ucc_geth.c
@@ -2196,9 +2196,7 @@ static int ucc_geth_alloc_tx(struct ucc_geth_private *ugeth)
UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT)
length += UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT;
if (uf_info->bd_mem_part == MEM_PART_SYSTEM) {
- u32 align = 4;
- if (UCC_GETH_TX_BD_RING_ALIGNMENT > 4)
- align = UCC_GETH_TX_BD_RING_ALIGNMENT;
+ u32 align = UCC_GETH_TX_BD_RING_ALIGNMENT;
ugeth->tx_bd_ring_offset[j] =
(u32) kmalloc((u32) (length + align), GFP_KERNEL);
@@ -2274,9 +2272,7 @@ static int ucc_geth_alloc_rx(struct ucc_geth_private *ugeth)
for (j = 0; j < ug_info->numQueuesRx; j++) {
length = ug_info->bdRingLenRx[j] * sizeof(struct qe_bd);
if (uf_info->bd_mem_part == MEM_PART_SYSTEM) {
- u32 align = 4;
- if (UCC_GETH_RX_BD_RING_ALIGNMENT > 4)
- align = UCC_GETH_RX_BD_RING_ALIGNMENT;
+ u32 align = UCC_GETH_RX_BD_RING_ALIGNMENT;
ugeth->rx_bd_ring_offset[j] =
(u32) kmalloc((u32) (length + align), GFP_KERNEL);
if (ugeth->rx_bd_ring_offset[j] != 0)
--
2.23.0
^ permalink raw reply related
* [PATCH 16/20] ethernet: ucc_geth: remove bd_mem_part and all associated code
From: Rasmus Villemoes @ 2020-12-05 19:17 UTC (permalink / raw)
To: Li Yang, David S. Miller, Jakub Kicinski
Cc: Rasmus Villemoes, Vladimir Oltean, linux-kernel, netdev,
linuxppc-dev, Zhao Qiang
In-Reply-To: <20201205191744.7847-1-rasmus.villemoes@prevas.dk>
The bd_mem_part member of ucc_geth_info always has the value
MEM_PART_SYSTEM, and AFAICT, there has never been any code setting it
to any other value. Moreover, muram is a somewhat precious resource,
so there's no point using that when normal memory serves just as well.
Apart from removing a lot of dead code, this is also motivated by
wanting to clean up the "store result from kmalloc() in a u32" mess.
Signed-off-by: Rasmus Villemoes <rasmus.villemoes@prevas.dk>
---
drivers/net/ethernet/freescale/ucc_geth.c | 106 ++++++----------------
include/soc/fsl/qe/qe.h | 6 --
include/soc/fsl/qe/ucc_fast.h | 1 -
3 files changed, 29 insertions(+), 84 deletions(-)
diff --git a/drivers/net/ethernet/freescale/ucc_geth.c b/drivers/net/ethernet/freescale/ucc_geth.c
index ccde42f547b8..c9f619908561 100644
--- a/drivers/net/ethernet/freescale/ucc_geth.c
+++ b/drivers/net/ethernet/freescale/ucc_geth.c
@@ -72,7 +72,6 @@ MODULE_PARM_DESC(debug, "Debug verbosity level (0=none, ..., 0xffff=all)");
static const struct ucc_geth_info ugeth_primary_info = {
.uf_info = {
- .bd_mem_part = MEM_PART_SYSTEM,
.rtsm = UCC_FAST_SEND_IDLES_BETWEEN_FRAMES,
.max_rx_buf_length = 1536,
/* adjusted at startup if max-speed 1000 */
@@ -1854,12 +1853,7 @@ static void ucc_geth_free_rx(struct ucc_geth_private *ugeth)
kfree(ugeth->rx_skbuff[i]);
- if (ugeth->ug_info->uf_info.bd_mem_part ==
- MEM_PART_SYSTEM)
- kfree((void *)ugeth->rx_bd_ring_offset[i]);
- else if (ugeth->ug_info->uf_info.bd_mem_part ==
- MEM_PART_MURAM)
- qe_muram_free(ugeth->rx_bd_ring_offset[i]);
+ kfree((void *)ugeth->rx_bd_ring_offset[i]);
ugeth->p_rx_bd_ring[i] = NULL;
}
}
@@ -1897,12 +1891,7 @@ static void ucc_geth_free_tx(struct ucc_geth_private *ugeth)
kfree(ugeth->tx_skbuff[i]);
if (ugeth->p_tx_bd_ring[i]) {
- if (ugeth->ug_info->uf_info.bd_mem_part ==
- MEM_PART_SYSTEM)
- kfree((void *)ugeth->tx_bd_ring_offset[i]);
- else if (ugeth->ug_info->uf_info.bd_mem_part ==
- MEM_PART_MURAM)
- qe_muram_free(ugeth->tx_bd_ring_offset[i]);
+ kfree((void *)ugeth->tx_bd_ring_offset[i]);
ugeth->p_tx_bd_ring[i] = NULL;
}
}
@@ -2060,13 +2049,6 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth)
ug_info = ugeth->ug_info;
uf_info = &ug_info->uf_info;
- if (!((uf_info->bd_mem_part == MEM_PART_SYSTEM) ||
- (uf_info->bd_mem_part == MEM_PART_MURAM))) {
- if (netif_msg_probe(ugeth))
- pr_err("Bad memory partition value\n");
- return -EINVAL;
- }
-
/* Rx BD lengths */
for (i = 0; i < ug_info->numQueuesRx; i++) {
if ((ug_info->bdRingLenRx[i] < UCC_GETH_RX_BD_RING_SIZE_MIN) ||
@@ -2186,6 +2168,8 @@ static int ucc_geth_alloc_tx(struct ucc_geth_private *ugeth)
/* Allocate Tx bds */
for (j = 0; j < ug_info->numQueuesTx; j++) {
+ u32 align = UCC_GETH_TX_BD_RING_ALIGNMENT;
+
/* Allocate in multiple of
UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT,
according to spec */
@@ -2195,24 +2179,15 @@ static int ucc_geth_alloc_tx(struct ucc_geth_private *ugeth)
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;
- if (uf_info->bd_mem_part == MEM_PART_SYSTEM) {
- u32 align = UCC_GETH_TX_BD_RING_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));
- } else if (uf_info->bd_mem_part == MEM_PART_MURAM) {
- ugeth->tx_bd_ring_offset[j] =
- qe_muram_alloc(length,
- UCC_GETH_TX_BD_RING_ALIGNMENT);
- if (!IS_ERR_VALUE(ugeth->tx_bd_ring_offset[j]))
- ugeth->p_tx_bd_ring[j] =
- (u8 __iomem *) qe_muram_addr(ugeth->
- tx_bd_ring_offset[j]);
- }
+
+ 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));
+
if (!ugeth->p_tx_bd_ring[j]) {
if (netif_msg_ifup(ugeth))
pr_err("Can not allocate memory for Tx bd rings\n");
@@ -2270,24 +2245,16 @@ static int ucc_geth_alloc_rx(struct ucc_geth_private *ugeth)
/* Allocate Rx bds */
for (j = 0; j < ug_info->numQueuesRx; j++) {
+ u32 align = UCC_GETH_RX_BD_RING_ALIGNMENT;
+
length = ug_info->bdRingLenRx[j] * sizeof(struct qe_bd);
- if (uf_info->bd_mem_part == MEM_PART_SYSTEM) {
- u32 align = UCC_GETH_RX_BD_RING_ALIGNMENT;
- 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));
- } else if (uf_info->bd_mem_part == MEM_PART_MURAM) {
- ugeth->rx_bd_ring_offset[j] =
- qe_muram_alloc(length,
- UCC_GETH_RX_BD_RING_ALIGNMENT);
- if (!IS_ERR_VALUE(ugeth->rx_bd_ring_offset[j]))
- ugeth->p_rx_bd_ring[j] =
- (u8 __iomem *) qe_muram_addr(ugeth->
- rx_bd_ring_offset[j]);
- }
+ 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));
+
if (!ugeth->p_rx_bd_ring[j]) {
if (netif_msg_ifup(ugeth))
pr_err("Can not allocate memory for Rx bd rings\n");
@@ -2552,20 +2519,11 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
endOfRing =
ugeth->p_tx_bd_ring[i] + (ug_info->bdRingLenTx[i] -
1) * sizeof(struct qe_bd);
- if (ugeth->ug_info->uf_info.bd_mem_part == MEM_PART_SYSTEM) {
- out_be32(&ugeth->p_send_q_mem_reg->sqqd[i].bd_ring_base,
- (u32) virt_to_phys(ugeth->p_tx_bd_ring[i]));
- out_be32(&ugeth->p_send_q_mem_reg->sqqd[i].
- last_bd_completed_address,
- (u32) virt_to_phys(endOfRing));
- } else if (ugeth->ug_info->uf_info.bd_mem_part ==
- MEM_PART_MURAM) {
- out_be32(&ugeth->p_send_q_mem_reg->sqqd[i].bd_ring_base,
- (u32)qe_muram_dma(ugeth->p_tx_bd_ring[i]));
- out_be32(&ugeth->p_send_q_mem_reg->sqqd[i].
- last_bd_completed_address,
- (u32)qe_muram_dma(endOfRing));
- }
+ out_be32(&ugeth->p_send_q_mem_reg->sqqd[i].bd_ring_base,
+ (u32) virt_to_phys(ugeth->p_tx_bd_ring[i]));
+ out_be32(&ugeth->p_send_q_mem_reg->sqqd[i].
+ last_bd_completed_address,
+ (u32) virt_to_phys(endOfRing));
}
/* schedulerbasepointer */
@@ -2784,14 +2742,8 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
/* Setup the table */
/* Assume BD rings are already established */
for (i = 0; i < ug_info->numQueuesRx; i++) {
- if (ugeth->ug_info->uf_info.bd_mem_part == MEM_PART_SYSTEM) {
- out_be32(&ugeth->p_rx_bd_qs_tbl[i].externalbdbaseptr,
- (u32) virt_to_phys(ugeth->p_rx_bd_ring[i]));
- } else if (ugeth->ug_info->uf_info.bd_mem_part ==
- MEM_PART_MURAM) {
- out_be32(&ugeth->p_rx_bd_qs_tbl[i].externalbdbaseptr,
- (u32)qe_muram_dma(ugeth->p_rx_bd_ring[i]));
- }
+ out_be32(&ugeth->p_rx_bd_qs_tbl[i].externalbdbaseptr,
+ (u32) virt_to_phys(ugeth->p_rx_bd_ring[i]));
/* rest of fields handled by QE */
}
diff --git a/include/soc/fsl/qe/qe.h b/include/soc/fsl/qe/qe.h
index 66f1afc393d1..4925a1b59dc9 100644
--- a/include/soc/fsl/qe/qe.h
+++ b/include/soc/fsl/qe/qe.h
@@ -27,12 +27,6 @@
#define QE_NUM_OF_BRGS 16
#define QE_NUM_OF_PORTS 1024
-/* Memory partitions
-*/
-#define MEM_PART_SYSTEM 0
-#define MEM_PART_SECONDARY 1
-#define MEM_PART_MURAM 2
-
/* Clocks and BRGs */
enum qe_clock {
QE_CLK_NONE = 0,
diff --git a/include/soc/fsl/qe/ucc_fast.h b/include/soc/fsl/qe/ucc_fast.h
index dc4e79468094..9696a5b9b5d1 100644
--- a/include/soc/fsl/qe/ucc_fast.h
+++ b/include/soc/fsl/qe/ucc_fast.h
@@ -146,7 +146,6 @@ struct ucc_fast_info {
resource_size_t regs;
int irq;
u32 uccm_mask;
- int bd_mem_part;
int brkpt_support;
int grant_support;
int tsa;
--
2.23.0
^ permalink raw reply related
* [PATCH 17/20] ethernet: ucc_geth: replace kmalloc_array()+for loop by kcalloc()
From: Rasmus Villemoes @ 2020-12-05 19:17 UTC (permalink / raw)
To: Li Yang, David S. Miller, Jakub Kicinski
Cc: Rasmus Villemoes, Vladimir Oltean, linux-kernel, netdev,
linuxppc-dev, Zhao Qiang
In-Reply-To: <20201205191744.7847-1-rasmus.villemoes@prevas.dk>
Signed-off-by: Rasmus Villemoes <rasmus.villemoes@prevas.dk>
---
drivers/net/ethernet/freescale/ucc_geth.c | 14 ++++----------
1 file changed, 4 insertions(+), 10 deletions(-)
diff --git a/drivers/net/ethernet/freescale/ucc_geth.c b/drivers/net/ethernet/freescale/ucc_geth.c
index c9f619908561..3aebea191b52 100644
--- a/drivers/net/ethernet/freescale/ucc_geth.c
+++ b/drivers/net/ethernet/freescale/ucc_geth.c
@@ -2203,8 +2203,8 @@ static int ucc_geth_alloc_tx(struct ucc_geth_private *ugeth)
for (j = 0; j < ug_info->numQueuesTx; j++) {
/* Setup the skbuff rings */
ugeth->tx_skbuff[j] =
- kmalloc_array(ugeth->ug_info->bdRingLenTx[j],
- sizeof(struct sk_buff *), GFP_KERNEL);
+ kcalloc(ugeth->ug_info->bdRingLenTx[j],
+ sizeof(struct sk_buff *), GFP_KERNEL);
if (ugeth->tx_skbuff[j] == NULL) {
if (netif_msg_ifup(ugeth))
@@ -2212,9 +2212,6 @@ static int ucc_geth_alloc_tx(struct ucc_geth_private *ugeth)
return -ENOMEM;
}
- for (i = 0; i < ugeth->ug_info->bdRingLenTx[j]; i++)
- ugeth->tx_skbuff[j][i] = NULL;
-
ugeth->skb_curtx[j] = ugeth->skb_dirtytx[j] = 0;
bd = ugeth->confBd[j] = ugeth->txBd[j] = ugeth->p_tx_bd_ring[j];
for (i = 0; i < ug_info->bdRingLenTx[j]; i++) {
@@ -2266,8 +2263,8 @@ static int ucc_geth_alloc_rx(struct ucc_geth_private *ugeth)
for (j = 0; j < ug_info->numQueuesRx; j++) {
/* Setup the skbuff rings */
ugeth->rx_skbuff[j] =
- kmalloc_array(ugeth->ug_info->bdRingLenRx[j],
- sizeof(struct sk_buff *), GFP_KERNEL);
+ kcalloc(ugeth->ug_info->bdRingLenRx[j],
+ sizeof(struct sk_buff *), GFP_KERNEL);
if (ugeth->rx_skbuff[j] == NULL) {
if (netif_msg_ifup(ugeth))
@@ -2275,9 +2272,6 @@ static int ucc_geth_alloc_rx(struct ucc_geth_private *ugeth)
return -ENOMEM;
}
- for (i = 0; i < ugeth->ug_info->bdRingLenRx[j]; i++)
- ugeth->rx_skbuff[j][i] = NULL;
-
ugeth->skb_currx[j] = 0;
bd = ugeth->rxBd[j] = ugeth->p_rx_bd_ring[j];
for (i = 0; i < ug_info->bdRingLenRx[j]; i++) {
--
2.23.0
^ permalink raw reply related
* [PATCH 18/20] ethernet: ucc_geth: add helper to replace repeated switch statements
From: Rasmus Villemoes @ 2020-12-05 19:17 UTC (permalink / raw)
To: Li Yang, David S. Miller, Jakub Kicinski
Cc: Rasmus Villemoes, Vladimir Oltean, linux-kernel, netdev,
linuxppc-dev, Zhao Qiang
In-Reply-To: <20201205191744.7847-1-rasmus.villemoes@prevas.dk>
The translation from the ucc_geth_num_of_threads enum value to the
actual count can be written somewhat more compactly with a small
lookup table, allowing us to replace the four switch statements.
Signed-off-by: Rasmus Villemoes <rasmus.villemoes@prevas.dk>
---
drivers/net/ethernet/freescale/ucc_geth.c | 100 +++++-----------------
1 file changed, 22 insertions(+), 78 deletions(-)
diff --git a/drivers/net/ethernet/freescale/ucc_geth.c b/drivers/net/ethernet/freescale/ucc_geth.c
index 3aebea191b52..a26d1feb7dab 100644
--- a/drivers/net/ethernet/freescale/ucc_geth.c
+++ b/drivers/net/ethernet/freescale/ucc_geth.c
@@ -70,6 +70,20 @@ static struct {
module_param_named(debug, debug.msg_enable, int, 0);
MODULE_PARM_DESC(debug, "Debug verbosity level (0=none, ..., 0xffff=all)");
+static int ucc_geth_thread_count(enum ucc_geth_num_of_threads idx)
+{
+ static const u8 count[] = {
+ [UCC_GETH_NUM_OF_THREADS_1] = 1,
+ [UCC_GETH_NUM_OF_THREADS_2] = 2,
+ [UCC_GETH_NUM_OF_THREADS_4] = 4,
+ [UCC_GETH_NUM_OF_THREADS_6] = 6,
+ [UCC_GETH_NUM_OF_THREADS_8] = 8,
+ };
+ if (idx >= ARRAY_SIZE(count))
+ return 0;
+ return count[idx];
+}
+
static const struct ucc_geth_info ugeth_primary_info = {
.uf_info = {
.rtsm = UCC_FAST_SEND_IDLES_BETWEEN_FRAMES,
@@ -668,32 +682,12 @@ static void dump_regs(struct ucc_geth_private *ugeth)
in_be32(&ugeth->ug_regs->scam));
if (ugeth->p_thread_data_tx) {
- int numThreadsTxNumerical;
- switch (ugeth->ug_info->numThreadsTx) {
- case UCC_GETH_NUM_OF_THREADS_1:
- numThreadsTxNumerical = 1;
- break;
- case UCC_GETH_NUM_OF_THREADS_2:
- numThreadsTxNumerical = 2;
- break;
- case UCC_GETH_NUM_OF_THREADS_4:
- numThreadsTxNumerical = 4;
- break;
- case UCC_GETH_NUM_OF_THREADS_6:
- numThreadsTxNumerical = 6;
- break;
- case UCC_GETH_NUM_OF_THREADS_8:
- numThreadsTxNumerical = 8;
- break;
- default:
- numThreadsTxNumerical = 0;
- break;
- }
+ int count = ucc_geth_thread_count(ugeth->ug_info->numThreadsTx);
pr_info("Thread data TXs:\n");
pr_info("Base address: 0x%08x\n",
(u32)ugeth->p_thread_data_tx);
- for (i = 0; i < numThreadsTxNumerical; i++) {
+ for (i = 0; i < count; i++) {
pr_info("Thread data TX[%d]:\n", i);
pr_info("Base address: 0x%08x\n",
(u32)&ugeth->p_thread_data_tx[i]);
@@ -702,32 +696,12 @@ static void dump_regs(struct ucc_geth_private *ugeth)
}
}
if (ugeth->p_thread_data_rx) {
- int numThreadsRxNumerical;
- switch (ugeth->ug_info->numThreadsRx) {
- case UCC_GETH_NUM_OF_THREADS_1:
- numThreadsRxNumerical = 1;
- break;
- case UCC_GETH_NUM_OF_THREADS_2:
- numThreadsRxNumerical = 2;
- break;
- case UCC_GETH_NUM_OF_THREADS_4:
- numThreadsRxNumerical = 4;
- break;
- case UCC_GETH_NUM_OF_THREADS_6:
- numThreadsRxNumerical = 6;
- break;
- case UCC_GETH_NUM_OF_THREADS_8:
- numThreadsRxNumerical = 8;
- break;
- default:
- numThreadsRxNumerical = 0;
- break;
- }
+ int count = ucc_geth_thread_count(ugeth->ug_info->numThreadsRx);
pr_info("Thread data RX:\n");
pr_info("Base address: 0x%08x\n",
(u32)ugeth->p_thread_data_rx);
- for (i = 0; i < numThreadsRxNumerical; i++) {
+ for (i = 0; i < count; i++) {
pr_info("Thread data RX[%d]:\n", i);
pr_info("Base address: 0x%08x\n",
(u32)&ugeth->p_thread_data_rx[i]);
@@ -2315,45 +2289,15 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
uf_regs = uccf->uf_regs;
ug_regs = ugeth->ug_regs;
- switch (ug_info->numThreadsRx) {
- case UCC_GETH_NUM_OF_THREADS_1:
- numThreadsRxNumerical = 1;
- break;
- case UCC_GETH_NUM_OF_THREADS_2:
- numThreadsRxNumerical = 2;
- break;
- case UCC_GETH_NUM_OF_THREADS_4:
- numThreadsRxNumerical = 4;
- break;
- case UCC_GETH_NUM_OF_THREADS_6:
- numThreadsRxNumerical = 6;
- break;
- case UCC_GETH_NUM_OF_THREADS_8:
- numThreadsRxNumerical = 8;
- break;
- default:
+ numThreadsRxNumerical = ucc_geth_thread_count(ug_info->numThreadsRx);
+ if (!numThreadsRxNumerical) {
if (netif_msg_ifup(ugeth))
pr_err("Bad number of Rx threads value\n");
return -EINVAL;
}
- switch (ug_info->numThreadsTx) {
- case UCC_GETH_NUM_OF_THREADS_1:
- numThreadsTxNumerical = 1;
- break;
- case UCC_GETH_NUM_OF_THREADS_2:
- numThreadsTxNumerical = 2;
- break;
- case UCC_GETH_NUM_OF_THREADS_4:
- numThreadsTxNumerical = 4;
- break;
- case UCC_GETH_NUM_OF_THREADS_6:
- numThreadsTxNumerical = 6;
- break;
- case UCC_GETH_NUM_OF_THREADS_8:
- numThreadsTxNumerical = 8;
- break;
- default:
+ numThreadsTxNumerical = ucc_geth_thread_count(ug_info->numThreadsTx);
+ if (!numThreadsTxNumerical) {
if (netif_msg_ifup(ugeth))
pr_err("Bad number of Tx threads value\n");
return -EINVAL;
--
2.23.0
^ permalink raw reply related
* [PATCH 19/20] ethernet: ucc_geth: inform the compiler that numQueues is always 1
From: Rasmus Villemoes @ 2020-12-05 19:17 UTC (permalink / raw)
To: Li Yang, David S. Miller, Jakub Kicinski
Cc: Rasmus Villemoes, Vladimir Oltean, linux-kernel, netdev,
linuxppc-dev, Zhao Qiang
In-Reply-To: <20201205191744.7847-1-rasmus.villemoes@prevas.dk>
The numQueuesTx and numQueuesRx members of struct ucc_geth_info are
never set to anything but 1, and never have been. It's unclear how
well the code supporting multiple queues would work. Until somebody
wants to play with enabling that, help the compiler eliminate a lot of
dead code and loops that are not really loops by creating static
inline helpers. If and when the numQueuesTx/numQueuesRx fields are
re-introduced, it suffices to update those helper to return the
appropriate field.
This cuts the .text segment of ucc_geth.o by 8%.
Signed-off-by: Rasmus Villemoes <rasmus.villemoes@prevas.dk>
---
drivers/net/ethernet/freescale/ucc_geth.c | 76 +++++++++++++----------
drivers/net/ethernet/freescale/ucc_geth.h | 2 -
2 files changed, 42 insertions(+), 36 deletions(-)
diff --git a/drivers/net/ethernet/freescale/ucc_geth.c b/drivers/net/ethernet/freescale/ucc_geth.c
index a26d1feb7dab..3cad2255bd97 100644
--- a/drivers/net/ethernet/freescale/ucc_geth.c
+++ b/drivers/net/ethernet/freescale/ucc_geth.c
@@ -84,6 +84,16 @@ static int ucc_geth_thread_count(enum ucc_geth_num_of_threads idx)
return count[idx];
}
+static inline int ucc_geth_tx_queues(const struct ucc_geth_info *info)
+{
+ return 1;
+}
+
+static inline int ucc_geth_rx_queues(const struct ucc_geth_info *info)
+{
+ return 1;
+}
+
static const struct ucc_geth_info ugeth_primary_info = {
.uf_info = {
.rtsm = UCC_FAST_SEND_IDLES_BETWEEN_FRAMES,
@@ -103,8 +113,6 @@ static const struct ucc_geth_info ugeth_primary_info = {
.tcrc = UCC_FAST_16_BIT_CRC,
.synl = UCC_FAST_SYNC_LEN_NOT_USED,
},
- .numQueuesTx = 1,
- .numQueuesRx = 1,
.extendedFilteringChainPointer = ((uint32_t) NULL),
.typeorlen = 3072 /*1536 */ ,
.nonBackToBackIfgPart1 = 0x40,
@@ -569,7 +577,7 @@ static void dump_bds(struct ucc_geth_private *ugeth)
int i;
int length;
- for (i = 0; i < ugeth->ug_info->numQueuesTx; i++) {
+ for (i = 0; i < ucc_geth_tx_queues(ugeth->ug_info); i++) {
if (ugeth->p_tx_bd_ring[i]) {
length =
(ugeth->ug_info->bdRingLenTx[i] *
@@ -578,7 +586,7 @@ static void dump_bds(struct ucc_geth_private *ugeth)
mem_disp(ugeth->p_tx_bd_ring[i], length);
}
}
- for (i = 0; i < ugeth->ug_info->numQueuesRx; i++) {
+ for (i = 0; i < ucc_geth_rx_queues(ugeth->ug_info); i++) {
if (ugeth->p_rx_bd_ring[i]) {
length =
(ugeth->ug_info->bdRingLenRx[i] *
@@ -876,7 +884,7 @@ static void dump_regs(struct ucc_geth_private *ugeth)
if (ugeth->p_send_q_mem_reg) {
pr_info("Send Q memory registers:\n");
pr_info("Base address: 0x%08x\n", (u32)ugeth->p_send_q_mem_reg);
- for (i = 0; i < ugeth->ug_info->numQueuesTx; i++) {
+ for (i = 0; i < ucc_geth_tx_queues(ugeth->ug_info); i++) {
pr_info("SQQD[%d]:\n", i);
pr_info("Base address: 0x%08x\n",
(u32)&ugeth->p_send_q_mem_reg->sqqd[i]);
@@ -908,7 +916,7 @@ static void dump_regs(struct ucc_geth_private *ugeth)
pr_info("RX IRQ coalescing tables:\n");
pr_info("Base address: 0x%08x\n",
(u32)ugeth->p_rx_irq_coalescing_tbl);
- for (i = 0; i < ugeth->ug_info->numQueuesRx; i++) {
+ for (i = 0; i < ucc_geth_rx_queues(ugeth->ug_info); i++) {
pr_info("RX IRQ coalescing table entry[%d]:\n", i);
pr_info("Base address: 0x%08x\n",
(u32)&ugeth->p_rx_irq_coalescing_tbl->
@@ -930,7 +938,7 @@ static void dump_regs(struct ucc_geth_private *ugeth)
if (ugeth->p_rx_bd_qs_tbl) {
pr_info("RX BD QS tables:\n");
pr_info("Base address: 0x%08x\n", (u32)ugeth->p_rx_bd_qs_tbl);
- for (i = 0; i < ugeth->ug_info->numQueuesRx; i++) {
+ for (i = 0; i < ucc_geth_rx_queues(ugeth->ug_info); i++) {
pr_info("RX BD QS table[%d]:\n", i);
pr_info("Base address: 0x%08x\n",
(u32)&ugeth->p_rx_bd_qs_tbl[i]);
@@ -1806,7 +1814,7 @@ static void ucc_geth_free_rx(struct ucc_geth_private *ugeth)
ug_info = ugeth->ug_info;
uf_info = &ug_info->uf_info;
- for (i = 0; i < ugeth->ug_info->numQueuesRx; i++) {
+ for (i = 0; i < ucc_geth_rx_queues(ugeth->ug_info); i++) {
if (ugeth->p_rx_bd_ring[i]) {
/* Return existing data buffers in ring */
bd = ugeth->p_rx_bd_ring[i];
@@ -1846,7 +1854,7 @@ static void ucc_geth_free_tx(struct ucc_geth_private *ugeth)
ug_info = ugeth->ug_info;
uf_info = &ug_info->uf_info;
- for (i = 0; i < ugeth->ug_info->numQueuesTx; i++) {
+ for (i = 0; i < ucc_geth_tx_queues(ugeth->ug_info); i++) {
bd = ugeth->p_tx_bd_ring[i];
if (!bd)
continue;
@@ -2024,7 +2032,7 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth)
uf_info = &ug_info->uf_info;
/* Rx BD lengths */
- for (i = 0; i < ug_info->numQueuesRx; i++) {
+ for (i = 0; i < ucc_geth_rx_queues(ug_info); i++) {
if ((ug_info->bdRingLenRx[i] < UCC_GETH_RX_BD_RING_SIZE_MIN) ||
(ug_info->bdRingLenRx[i] %
UCC_GETH_RX_BD_RING_SIZE_ALIGNMENT)) {
@@ -2035,7 +2043,7 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth)
}
/* Tx BD lengths */
- for (i = 0; i < ug_info->numQueuesTx; i++) {
+ for (i = 0; i < ucc_geth_tx_queues(ug_info); i++) {
if (ug_info->bdRingLenTx[i] < UCC_GETH_TX_BD_RING_SIZE_MIN) {
if (netif_msg_probe(ugeth))
pr_err("Tx BD ring length must be no smaller than 2\n");
@@ -2052,14 +2060,14 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth)
}
/* num Tx queues */
- if (ug_info->numQueuesTx > NUM_TX_QUEUES) {
+ if (ucc_geth_tx_queues(ug_info) > NUM_TX_QUEUES) {
if (netif_msg_probe(ugeth))
pr_err("number of tx queues too large\n");
return -EINVAL;
}
/* num Rx queues */
- if (ug_info->numQueuesRx > NUM_RX_QUEUES) {
+ if (ucc_geth_rx_queues(ug_info) > NUM_RX_QUEUES) {
if (netif_msg_probe(ugeth))
pr_err("number of rx queues too large\n");
return -EINVAL;
@@ -2067,7 +2075,7 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth)
/* l2qt */
for (i = 0; i < UCC_GETH_VLAN_PRIORITY_MAX; i++) {
- if (ug_info->l2qt[i] >= ug_info->numQueuesRx) {
+ if (ug_info->l2qt[i] >= ucc_geth_rx_queues(ug_info)) {
if (netif_msg_probe(ugeth))
pr_err("VLAN priority table entry must not be larger than number of Rx queues\n");
return -EINVAL;
@@ -2076,7 +2084,7 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth)
/* l3qt */
for (i = 0; i < UCC_GETH_IP_PRIORITY_MAX; i++) {
- if (ug_info->l3qt[i] >= ug_info->numQueuesRx) {
+ if (ug_info->l3qt[i] >= ucc_geth_rx_queues(ug_info)) {
if (netif_msg_probe(ugeth))
pr_err("IP priority table entry must not be larger than number of Rx queues\n");
return -EINVAL;
@@ -2099,10 +2107,10 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth)
/* Generate uccm_mask for receive */
uf_info->uccm_mask = ug_info->eventRegMask & UCCE_OTHER;/* Errors */
- for (i = 0; i < ug_info->numQueuesRx; i++)
+ for (i = 0; i < ucc_geth_rx_queues(ug_info); i++)
uf_info->uccm_mask |= (UCC_GETH_UCCE_RXF0 << i);
- for (i = 0; i < ug_info->numQueuesTx; i++)
+ for (i = 0; i < ucc_geth_tx_queues(ug_info); i++)
uf_info->uccm_mask |= (UCC_GETH_UCCE_TXB0 << i);
/* Initialize the general fast UCC block. */
if (ucc_fast_init(uf_info, &ugeth->uccf)) {
@@ -2141,7 +2149,7 @@ static int ucc_geth_alloc_tx(struct ucc_geth_private *ugeth)
uf_info = &ug_info->uf_info;
/* Allocate Tx bds */
- for (j = 0; j < ug_info->numQueuesTx; j++) {
+ for (j = 0; j < ucc_geth_tx_queues(ug_info); j++) {
u32 align = UCC_GETH_TX_BD_RING_ALIGNMENT;
/* Allocate in multiple of
@@ -2174,7 +2182,7 @@ static int ucc_geth_alloc_tx(struct ucc_geth_private *ugeth)
}
/* Init Tx bds */
- for (j = 0; j < ug_info->numQueuesTx; j++) {
+ for (j = 0; j < ucc_geth_tx_queues(ug_info); j++) {
/* Setup the skbuff rings */
ugeth->tx_skbuff[j] =
kcalloc(ugeth->ug_info->bdRingLenTx[j],
@@ -2215,7 +2223,7 @@ static int ucc_geth_alloc_rx(struct ucc_geth_private *ugeth)
uf_info = &ug_info->uf_info;
/* Allocate Rx bds */
- for (j = 0; j < ug_info->numQueuesRx; j++) {
+ for (j = 0; j < ucc_geth_rx_queues(ug_info); j++) {
u32 align = UCC_GETH_RX_BD_RING_ALIGNMENT;
length = ug_info->bdRingLenRx[j] * sizeof(struct qe_bd);
@@ -2234,7 +2242,7 @@ static int ucc_geth_alloc_rx(struct ucc_geth_private *ugeth)
}
/* Init Rx bds */
- for (j = 0; j < ug_info->numQueuesRx; j++) {
+ for (j = 0; j < ucc_geth_rx_queues(ug_info); j++) {
/* Setup the skbuff rings */
ugeth->rx_skbuff[j] =
kcalloc(ugeth->ug_info->bdRingLenRx[j],
@@ -2437,7 +2445,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
/* SQPTR */
/* Size varies with number of Tx queues */
ugeth->send_q_mem_reg_offset =
- qe_muram_alloc(ug_info->numQueuesTx *
+ qe_muram_alloc(ucc_geth_tx_queues(ug_info) *
sizeof(struct ucc_geth_send_queue_qd),
UCC_GETH_SEND_QUEUE_QUEUE_DESCRIPTOR_ALIGNMENT);
if (IS_ERR_VALUE(ugeth->send_q_mem_reg_offset)) {
@@ -2453,7 +2461,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
/* Setup the table */
/* Assume BD rings are already established */
- for (i = 0; i < ug_info->numQueuesTx; i++) {
+ for (i = 0; i < ucc_geth_tx_queues(ug_info); i++) {
endOfRing =
ugeth->p_tx_bd_ring[i] + (ug_info->bdRingLenTx[i] -
1) * sizeof(struct qe_bd);
@@ -2466,7 +2474,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
/* schedulerbasepointer */
- if (ug_info->numQueuesTx > 1) {
+ if (ucc_geth_tx_queues(ug_info) > 1) {
/* scheduler exists only if more than 1 tx queue */
ugeth->scheduler_offset =
qe_muram_alloc(sizeof(struct ucc_geth_scheduler),
@@ -2529,11 +2537,11 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
/* temoder */
/* Already has speed set */
- if (ug_info->numQueuesTx > 1)
+ if (ucc_geth_tx_queues(ug_info) > 1)
temoder |= TEMODER_SCHEDULER_ENABLE;
if (ug_info->ipCheckSumGenerate)
temoder |= TEMODER_IP_CHECKSUM_GENERATE;
- temoder |= ((ug_info->numQueuesTx - 1) << TEMODER_NUM_OF_QUEUES_SHIFT);
+ temoder |= ((ucc_geth_tx_queues(ug_info) - 1) << TEMODER_NUM_OF_QUEUES_SHIFT);
out_be16(&ugeth->p_tx_glbl_pram->temoder, temoder);
/* Function code register value to be used later */
@@ -2597,7 +2605,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
/* Size varies with number of Rx queues */
ugeth->rx_irq_coalescing_tbl_offset =
- qe_muram_alloc(ug_info->numQueuesRx *
+ qe_muram_alloc(ucc_geth_rx_queues(ug_info) *
sizeof(struct ucc_geth_rx_interrupt_coalescing_entry)
+ 4, UCC_GETH_RX_INTERRUPT_COALESCING_ALIGNMENT);
if (IS_ERR_VALUE(ugeth->rx_irq_coalescing_tbl_offset)) {
@@ -2613,7 +2621,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
ugeth->rx_irq_coalescing_tbl_offset);
/* Fill interrupt coalescing table */
- for (i = 0; i < ug_info->numQueuesRx; i++) {
+ for (i = 0; i < ucc_geth_rx_queues(ug_info); i++) {
out_be32(&ugeth->p_rx_irq_coalescing_tbl->coalescingentry[i].
interruptcoalescingmaxvalue,
ug_info->interruptcoalescingmaxvalue[i]);
@@ -2662,7 +2670,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
/* RBDQPTR */
/* Size varies with number of Rx queues */
ugeth->rx_bd_qs_tbl_offset =
- qe_muram_alloc(ug_info->numQueuesRx *
+ qe_muram_alloc(ucc_geth_rx_queues(ug_info) *
(sizeof(struct ucc_geth_rx_bd_queues_entry) +
sizeof(struct ucc_geth_rx_prefetched_bds)),
UCC_GETH_RX_BD_QUEUES_ALIGNMENT);
@@ -2679,7 +2687,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
/* Setup the table */
/* Assume BD rings are already established */
- for (i = 0; i < ug_info->numQueuesRx; i++) {
+ for (i = 0; i < ucc_geth_rx_queues(ug_info); i++) {
out_be32(&ugeth->p_rx_bd_qs_tbl[i].externalbdbaseptr,
(u32) virt_to_phys(ugeth->p_rx_bd_ring[i]));
/* rest of fields handled by QE */
@@ -2702,7 +2710,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
ug_info->
vlanOperationNonTagged << REMODER_VLAN_OPERATION_NON_TAGGED_SHIFT;
remoder |= ug_info->rxQoSMode << REMODER_RX_QOS_MODE_SHIFT;
- remoder |= ((ug_info->numQueuesRx - 1) << REMODER_NUM_OF_QUEUES_SHIFT);
+ remoder |= ((ucc_geth_rx_queues(ug_info) - 1) << REMODER_NUM_OF_QUEUES_SHIFT);
if (ug_info->ipCheckSumCheck)
remoder |= REMODER_IP_CHECKSUM_CHECK;
if (ug_info->ipAddressAlignment)
@@ -2861,7 +2869,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
}
/* Load Rx bds with buffers */
- for (i = 0; i < ug_info->numQueuesRx; i++) {
+ for (i = 0; i < ucc_geth_rx_queues(ug_info); i++) {
if ((ret_val = rx_bd_buffer_set(ugeth, (u8) i)) != 0) {
if (netif_msg_ifup(ugeth))
pr_err("Can not fill Rx bds with buffers\n");
@@ -3132,12 +3140,12 @@ static int ucc_geth_poll(struct napi_struct *napi, int budget)
/* Tx event processing */
spin_lock(&ugeth->lock);
- for (i = 0; i < ug_info->numQueuesTx; i++)
+ for (i = 0; i < ucc_geth_tx_queues(ug_info); i++)
ucc_geth_tx(ugeth->ndev, i);
spin_unlock(&ugeth->lock);
howmany = 0;
- for (i = 0; i < ug_info->numQueuesRx; i++)
+ for (i = 0; i < ucc_geth_rx_queues(ug_info); i++)
howmany += ucc_geth_rx(ugeth, i, budget - howmany);
if (howmany < budget) {
diff --git a/drivers/net/ethernet/freescale/ucc_geth.h b/drivers/net/ethernet/freescale/ucc_geth.h
index be47fa8ced15..6539fed9cc22 100644
--- a/drivers/net/ethernet/freescale/ucc_geth.h
+++ b/drivers/net/ethernet/freescale/ucc_geth.h
@@ -1077,8 +1077,6 @@ struct ucc_geth_tad_params {
/* GETH protocol initialization structure */
struct ucc_geth_info {
struct ucc_fast_info uf_info;
- u8 numQueuesTx;
- u8 numQueuesRx;
int ipCheckSumCheck;
int ipCheckSumGenerate;
int rxExtendedFiltering;
--
2.23.0
^ permalink raw reply related
* [PATCH 20/20] ethernet: ucc_geth: simplify rx/tx allocations
From: Rasmus Villemoes @ 2020-12-05 19:17 UTC (permalink / raw)
To: Li Yang, David S. Miller, Jakub Kicinski
Cc: Rasmus Villemoes, Vladimir Oltean, linux-kernel, netdev,
linuxppc-dev, Zhao Qiang
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
^ permalink raw reply related
* Re: [GIT PULL] Please pull powerpc/linux.git powerpc-5.10-5 tag
From: pr-tracker-bot @ 2020-12-05 19:21 UTC (permalink / raw)
To: Michael Ellerman
Cc: srikar, peterz, linuxppc-dev, mahesh, npiggin, linux-kernel,
groug, Linus Torvalds
In-Reply-To: <87im9gtpge.fsf@mpe.ellerman.id.au>
The pull request you sent on Sat, 05 Dec 2020 23:19:45 +1100:
> https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git tags/powerpc-5.10-5
has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/32f741b02f1a84dd15cdaf74ea3c8d724f812318
Thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html
^ permalink raw reply
* Re: [PATCH 11/20] ethernet: ucc_geth: fix use-after-free in ucc_geth_remove()
From: Jakub Kicinski @ 2020-12-05 20:48 UTC (permalink / raw)
To: Rasmus Villemoes
Cc: Vladimir Oltean, linux-kernel, Li Yang, netdev, linuxppc-dev,
David S. Miller, Zhao Qiang
In-Reply-To: <20201205191744.7847-12-rasmus.villemoes@prevas.dk>
On Sat, 5 Dec 2020 20:17:34 +0100 Rasmus Villemoes wrote:
> - unregister_netdev(dev);
> - free_netdev(dev);
> ucc_geth_memclean(ugeth);
> if (of_phy_is_fixed_link(np))
> of_phy_deregister_fixed_link(np);
> of_node_put(ugeth->ug_info->tbi_node);
> of_node_put(ugeth->ug_info->phy_node);
> + unregister_netdev(dev);
> + free_netdev(dev);
Are you sure you want to move the unregister_netdev() as well as the
free?
^ permalink raw reply
* Re: [PATCH 00/20] ethernet: ucc_geth: assorted fixes and simplifications
From: Jakub Kicinski @ 2020-12-05 20:53 UTC (permalink / raw)
To: Rasmus Villemoes
Cc: netdev, linux-kernel, Li Yang, Vladimir Oltean, linuxppc-dev,
David S. Miller, linux-arm-kernel, Qiang Zhao
In-Reply-To: <20201205191744.7847-1-rasmus.villemoes@prevas.dk>
On Sat, 5 Dec 2020 20:17:23 +0100 Rasmus Villemoes wrote:
> While trying to figure out how to allow bumping the MTU with the
> ucc_geth driver, I fell into a rabbit hole and stumbled on a whole
> bunch of issues of varying importance - some are outright bug fixes,
> while most are a matter of simplifying the code to make it more
> accessible.
>
> At the end of digging around the code and data sheet to figure out how
> it all works, I think the MTU issue might be fixed by a one-liner, but
> I'm not sure it can be that simple. It does seem to work (ping -s X
> works for larger values of X, and wireshark confirms that the packets
> are not fragmented).
>
> Re patch 2, someone in NXP should check how the hardware actually
> works and make an updated reference manual available.
Looks like a nice clean up on a quick look.
Please separate patches 1 and 11 (which are the two bug fixes I see)
rebase (retest) and post them against the net tree:
https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git/
so they are available for backports.
The reset should go into net-next:
https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git/
Please indicate the tree in the tag like [PATCH net] or [PATCH
net-next] so the test bots know which base to use for testing.
Thanks!
^ permalink raw reply
* Re: [PATCH 11/20] ethernet: ucc_geth: fix use-after-free in ucc_geth_remove()
From: Rasmus Villemoes @ 2020-12-05 21:04 UTC (permalink / raw)
To: Jakub Kicinski
Cc: Vladimir Oltean, linux-kernel, Li Yang, netdev, linuxppc-dev,
David S. Miller, Zhao Qiang
In-Reply-To: <20201205124859.60d045e6@kicinski-fedora-pc1c0hjn.DHCP.thefacebook.com>
On 05/12/2020 21.48, Jakub Kicinski wrote:
> On Sat, 5 Dec 2020 20:17:34 +0100 Rasmus Villemoes wrote:
>> - unregister_netdev(dev);
>> - free_netdev(dev);
>> ucc_geth_memclean(ugeth);
>> if (of_phy_is_fixed_link(np))
>> of_phy_deregister_fixed_link(np);
>> of_node_put(ugeth->ug_info->tbi_node);
>> of_node_put(ugeth->ug_info->phy_node);
>> + unregister_netdev(dev);
>> + free_netdev(dev);
>
> Are you sure you want to move the unregister_netdev() as well as the
> free?
>
Hm, dunno, I don't think it's needed per se, but it also shouldn't hurt
from what I can tell. It seems more natural that they go together, but
if you prefer a minimal patch that's of course also possible.
I only noticed because I needed to add a free of the ug_info in a later
patch.
Rasmus
^ permalink raw reply
* Re: [PATCH 00/20] ethernet: ucc_geth: assorted fixes and simplifications
From: Rasmus Villemoes @ 2020-12-05 21:11 UTC (permalink / raw)
To: Jakub Kicinski
Cc: netdev, linux-kernel, Li Yang, Vladimir Oltean, linuxppc-dev,
David S. Miller, linux-arm-kernel, Qiang Zhao
In-Reply-To: <20201205125351.41e89579@kicinski-fedora-pc1c0hjn.DHCP.thefacebook.com>
On 05/12/2020 21.53, Jakub Kicinski wrote:
> On Sat, 5 Dec 2020 20:17:23 +0100 Rasmus Villemoes wrote:
>> While trying to figure out how to allow bumping the MTU with the
>> ucc_geth driver, I fell into a rabbit hole and stumbled on a whole
>> bunch of issues of varying importance - some are outright bug fixes,
>> while most are a matter of simplifying the code to make it more
>> accessible.
>>
>> At the end of digging around the code and data sheet to figure out how
>> it all works, I think the MTU issue might be fixed by a one-liner, but
>> I'm not sure it can be that simple. It does seem to work (ping -s X
>> works for larger values of X, and wireshark confirms that the packets
>> are not fragmented).
>>
>> Re patch 2, someone in NXP should check how the hardware actually
>> works and make an updated reference manual available.
>
> Looks like a nice clean up on a quick look.
>
> Please separate patches 1 and 11 (which are the two bug fixes I see)
I think patch 2 is a bug fix as well, but I'd like someone from NXP to
comment.
> rebase (retest) and post them against the net tree:
>
> https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git/
So I thought this would go through Li Yang's tree. That's where my
previous QE related patches have gone through, and at least some need
some input from NXP folks - and what MAINTAINERS suggests. So not
marking the patches with net or net-next was deliberate. But I'm happy
to rearrange and send to net/net-next as appropriate if that's what you
and Li Yang can agree to.
Thanks,
Rasmus
^ permalink raw reply
* Re: [PATCH 11/20] ethernet: ucc_geth: fix use-after-free in ucc_geth_remove()
From: Jakub Kicinski @ 2020-12-05 21:19 UTC (permalink / raw)
To: Rasmus Villemoes
Cc: Vladimir Oltean, linux-kernel, Li Yang, netdev, linuxppc-dev,
David S. Miller, Zhao Qiang
In-Reply-To: <4d35ef11-b1eb-c450-2937-94e20fa9a213@prevas.dk>
On Sat, 5 Dec 2020 22:04:28 +0100 Rasmus Villemoes wrote:
> On 05/12/2020 21.48, Jakub Kicinski wrote:
> > On Sat, 5 Dec 2020 20:17:34 +0100 Rasmus Villemoes wrote:
> >> - unregister_netdev(dev);
> >> - free_netdev(dev);
> >> ucc_geth_memclean(ugeth);
> >> if (of_phy_is_fixed_link(np))
> >> of_phy_deregister_fixed_link(np);
> >> of_node_put(ugeth->ug_info->tbi_node);
> >> of_node_put(ugeth->ug_info->phy_node);
> >> + unregister_netdev(dev);
> >> + free_netdev(dev);
> >
> > Are you sure you want to move the unregister_netdev() as well as the
> > free?
>
> Hm, dunno, I don't think it's needed per se, but it also shouldn't hurt
> from what I can tell. It seems more natural that they go together, but
> if you prefer a minimal patch that's of course also possible.
I was concerned about the fact that we free things and release
references while the device may still be up (given that it's
unregister_netdev() that will take it down).
> I only noticed because I needed to add a free of the ug_info in a later
> patch.
^ permalink raw reply
* Re: [PATCH 00/20] ethernet: ucc_geth: assorted fixes and simplifications
From: Jakub Kicinski @ 2020-12-05 21:27 UTC (permalink / raw)
To: Rasmus Villemoes
Cc: netdev, linux-kernel, Li Yang, Vladimir Oltean, linuxppc-dev,
David S. Miller, linux-arm-kernel, Qiang Zhao
In-Reply-To: <7e78df84-0035-6935-acb0-adbd0c648128@prevas.dk>
On Sat, 5 Dec 2020 22:11:39 +0100 Rasmus Villemoes wrote:
> > Looks like a nice clean up on a quick look.
> >
> > Please separate patches 1 and 11 (which are the two bug fixes I see)
>
> I think patch 2 is a bug fix as well, but I'd like someone from NXP to
> comment.
Sure, makes sense.
> > rebase (retest) and post them against the net tree:
> >
> > https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git/
>
> So I thought this would go through Li Yang's tree. That's where my
> previous QE related patches have gone through, and at least some need
> some input from NXP folks - and what MAINTAINERS suggests. So not
> marking the patches with net or net-next was deliberate. But I'm happy
> to rearrange and send to net/net-next as appropriate if that's what you
> and Li Yang can agree to.
Ah, now I noticed you didn't CC all of the patches to netdev.
Please don't do that, build bots won't be able to validate partially
posted patches.
^ permalink raw reply
* Re: [PATCH 11/20] ethernet: ucc_geth: fix use-after-free in ucc_geth_remove()
From: Rasmus Villemoes @ 2020-12-05 21:35 UTC (permalink / raw)
To: Jakub Kicinski
Cc: Vladimir Oltean, linux-kernel, Li Yang, netdev, linuxppc-dev,
David S. Miller, Zhao Qiang
In-Reply-To: <20201205131928.7d5c8e59@kicinski-fedora-pc1c0hjn.DHCP.thefacebook.com>
On 05/12/2020 22.19, Jakub Kicinski wrote:
> On Sat, 5 Dec 2020 22:04:28 +0100 Rasmus Villemoes wrote:
>> On 05/12/2020 21.48, Jakub Kicinski wrote:
>>> On Sat, 5 Dec 2020 20:17:34 +0100 Rasmus Villemoes wrote:
>>>> - unregister_netdev(dev);
>>>> - free_netdev(dev);
>>>> ucc_geth_memclean(ugeth);
>>>> if (of_phy_is_fixed_link(np))
>>>> of_phy_deregister_fixed_link(np);
>>>> of_node_put(ugeth->ug_info->tbi_node);
>>>> of_node_put(ugeth->ug_info->phy_node);
>>>> + unregister_netdev(dev);
>>>> + free_netdev(dev);
>>>
>>> Are you sure you want to move the unregister_netdev() as well as the
>>> free?
>>
>> Hm, dunno, I don't think it's needed per se, but it also shouldn't hurt
>> from what I can tell. It seems more natural that they go together, but
>> if you prefer a minimal patch that's of course also possible.
>
> I was concerned about the fact that we free things and release
> references while the device may still be up (given that it's
> unregister_netdev() that will take it down).
I guess you're right. I'll fix it locally (and pull the patch earlier)
and wait a few days with sending an updated version to give Li Yang some
time to say if he wants to handle the series or not.
Thanks,
Rasmus
^ permalink raw reply
* Re: [PATCH 00/20] ethernet: ucc_geth: assorted fixes and simplifications
From: Rasmus Villemoes @ 2020-12-05 21:36 UTC (permalink / raw)
To: Jakub Kicinski
Cc: netdev, linux-kernel, Li Yang, Vladimir Oltean, linuxppc-dev,
David S. Miller, linux-arm-kernel, Qiang Zhao
In-Reply-To: <20201205132716.4c68e35d@kicinski-fedora-pc1c0hjn.DHCP.thefacebook.com>
On 05/12/2020 22.27, Jakub Kicinski wrote:
> On Sat, 5 Dec 2020 22:11:39 +0100 Rasmus Villemoes wrote:
>>> rebase (retest) and post them against the net tree:
>>>
>>> https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git/
>>
>> So I thought this would go through Li Yang's tree. That's where my
>> previous QE related patches have gone through, and at least some need
>> some input from NXP folks - and what MAINTAINERS suggests. So not
>> marking the patches with net or net-next was deliberate. But I'm happy
>> to rearrange and send to net/net-next as appropriate if that's what you
>> and Li Yang can agree to.
>
> Ah, now I noticed you didn't CC all of the patches to netdev.
> Please don't do that, build bots won't be able to validate partially
> posted patches.
Hm, I mostly rely on scripts/get_maintainer.pl, invoked via a script I
give to --to-cmd/--cc-cmd. They are all sent to LKML, so buildbots
should be OK. But regardless of whether Li Yang will be handling it or
not, I'll try to remember to cc the whole series to netdev when resending.
Rasmus
^ permalink raw reply
* Re: [PATCH 11/20] ethernet: ucc_geth: fix use-after-free in ucc_geth_remove()
From: Rasmus Villemoes @ 2020-12-05 21:50 UTC (permalink / raw)
To: Jakub Kicinski
Cc: Vladimir Oltean, linux-kernel, Li Yang, netdev, linuxppc-dev,
David S. Miller, Zhao Qiang
In-Reply-To: <4d35ef11-b1eb-c450-2937-94e20fa9a213@prevas.dk>
> I only noticed because I needed to add a free of the ug_info in a later
> patch.
Where, ironically, I add a use-after-free bug by freeing ug_info before
the ucc_geth_memclean() call.
:facepalm:
^ permalink raw reply
* Re: [PATCH 2/8] x86: use exit_lazy_tlb rather than membarrier_mm_sync_core_before_usermode
From: Nicholas Piggin @ 2020-12-05 23:14 UTC (permalink / raw)
To: Andy Lutomirski
Cc: linux-arch, Arnd Bergmann, Peter Zijlstra, X86 ML, LKML, Linux-MM,
Mathieu Desnoyers, Andy Lutomirski, linuxppc-dev
In-Reply-To: <116A6B40-C77B-4B6A-897B-18342CD62CEC@amacapital.net>
Excerpts from Andy Lutomirski's message of December 6, 2020 2:11 am:
>
>> On Dec 5, 2020, at 12:00 AM, Nicholas Piggin <npiggin@gmail.com> wrote:
>>
>>
>> I disagree. Until now nobody following it noticed that the mm gets
>> un-lazied in other cases, because that was not too clear from the
>> code (only indirectly using non-standard terminology in the arch
>> support document).
>
>> In other words, membarrier needs a special sync to deal with the case
>> when a kthread takes the mm.
>
> I don’t think this is actually true. Somehow the x86 oddities about
> CR3 writes leaked too much into the membarrier core code and comments.
> (I doubt this is x86 specific. The actual x86 specific part seems to
> be that we can return to user mode without syncing the instruction
> stream.)
>
> As far as I can tell, membarrier doesn’t care at all about laziness.
> Membarrier cares about rq->curr->mm. The fact that a cpu can switch
> its actual loaded mm without scheduling at all (on x86 at least) is
> entirely beside the point except insofar as it has an effect on
> whether a subsequent switch_mm() call serializes.
Core membarrier itself doesn't care about laziness, which is why the
membarrier flush should go in exit_lazy_tlb() or other x86 specific
code (at least until more architectures did the same thing and we moved
it into generic code). I just meant this non-serialising return as
documented in the membarrier arch enablement doc specifies the lazy tlb
requirement.
If an mm was lazy tlb for a kernel thread and then it becomes unlazy,
and if switch_mm is serialising but return to user is not, then you
need a serialising instruction somewhere before return to user. unlazy
is the logical place to add that, because the lazy tlb mm (i.e.,
switching to a kernel thread and back without switching mm) is what
opens the hole.
> If we notify
> membarrier about x86’s asynchronous CR3 writes, then membarrier needs
> to understand what to do with them, which results in an unmaintainable
> mess in membarrier *and* in the x86 code.
How do you mean? exit_lazy_tlb is the opposite, core scheduler notifying
arch code about when an mm becomes not-lazy, and nothing to do with
membarrier at all even. It's a convenient hook to do your un-lazying.
I guess you can do it also checking things in switch_mm and keeping state
in arch code, I don't think that's necessarily the best place to put it.
So membarrier code is unchanged (it cares that the serialise is done at
un-lazy time), core code is simpler (no knowledge of this membarrier
quirk and it already knows about lazy-tlb so the calls actually improve
the documentation), and x86 code I would argue becomes nicer (or no real
difference at worst) because you can move some exit lazy tlb handling to
that specific call rather than decipher it from switch_mm.
>
> I’m currently trying to document how membarrier actually works, and
> hopefully this will result in untangling membarrier from mmdrop() and
> such.
That would be nice.
>
> A silly part of this is that x86 already has a high quality
> implementation of most of membarrier(): flush_tlb_mm(). If you flush
> an mm’s TLB, we carefully propagate the flush to all threads, with
> attention to memory ordering. We can’t use this directly as an
> arch-specific implementation of membarrier because it has the annoying
> side affect of flushing the TLB and because upcoming hardware might be
> able to flush without guaranteeing a core sync. (Upcoming means Zen
> 3, but the Zen 3 implementation is sadly not usable by Linux.)
>
A hardware broadcast TLB flush, you mean? What makes it unusable by
Linux out of curiosity?
^ permalink raw reply
* Re: [PATCH 2/8] x86: use exit_lazy_tlb rather than membarrier_mm_sync_core_before_usermode
From: Andy Lutomirski @ 2020-12-06 0:36 UTC (permalink / raw)
To: Nicholas Piggin
Cc: linux-arch, Arnd Bergmann, Peter Zijlstra, X86 ML, LKML, Linux-MM,
Mathieu Desnoyers, Andy Lutomirski, linuxppc-dev
In-Reply-To: <1607209402.fogfsh8ov4.astroid@bobo.none>
On Sat, Dec 5, 2020 at 3:15 PM Nicholas Piggin <npiggin@gmail.com> wrote:
>
> Excerpts from Andy Lutomirski's message of December 6, 2020 2:11 am:
> >
> If an mm was lazy tlb for a kernel thread and then it becomes unlazy,
> and if switch_mm is serialising but return to user is not, then you
> need a serialising instruction somewhere before return to user. unlazy
> is the logical place to add that, because the lazy tlb mm (i.e.,
> switching to a kernel thread and back without switching mm) is what
> opens the hole.
The issue here is that unlazying on x86 sometimes serializes and
sometimes doesn't. It's straightforward to add logic to the x86 code
to serialize specifically in the case where membarrier core sync is
registered and unlazying would otherwise not serialize, but trying to
define sensible semantics for this in a call to core code seems
complicated. (Specifically, the x86 code only sometimes sends IPIs to
lazy CPUs for TLB flushes. If an IPI is skipped, then unlazying will
flush the TLB, and that operation is serializing.
The whole lazy thing is IMO a red herring for membarrier(). The
membarrier() logic requires that switching *logical* mms
(rq->curr->mm) serializes before user mode if the new mm is registered
for core sync. AFAICT the only architecture on which this isn't
automatic is x86, and somehow the logic turned into "actually changing
rq->curr->mm serializes, but unlazying only sometimes serializes, so
we need to do an extra serialization step on unlazying operations"
instead of "tell x86 to make sure it always serializes when it
switches logical mms". The latter is easy to specify and easy to
implement.
>
> How do you mean? exit_lazy_tlb is the opposite, core scheduler notifying
> arch code about when an mm becomes not-lazy, and nothing to do with
> membarrier at all even. It's a convenient hook to do your un-lazying.
> I guess you can do it also checking things in switch_mm and keeping state
> in arch code, I don't think that's necessarily the best place to put it.
I'm confused. I just re-read your patches, and it looks like you have
arch code calling exit_lazy_tlb(). On x86, if we do a TLB shootdown
IPI to a lazy CPU, the IPI handler will unlazy that CPU (by switching
to init_mm for real), and we have no way to notify the core scheduler
about this, so we don't. The result is that the core scheduler state
and the x86 state gets out of sync. If the core scheduler
subsequently switches us back to the mm that it thinks we were still
using lazily them, from the x86 code's perspective, we're not
unlazying -- we're just doing a regular switch from init_mm to some
other mm. This is why x86's switch_mm_irqs_off() totally ignores its
'prev' argument.
I'm honestly a bit surprised that other architectures don't do the
same thing. I suppose that some architectures don't use shootdown
IPIs at all, in which case there doesn't seem to be any good reason to
aggressively unlazy.
(Oddly, despite the fact that, since Ivy Bridge, x86 has a "just flush
the TLB" instruction, that instruction is considerably slower than the
old "switch mm and flush" operation. So the operation "switch to
init_mm" is only ever any slower than "flush and stay lazy" if we get
lucky and unlazy to the same mm before we get a second TLB shootdown
*and* if unlazying to the same mm would not have needed to flush. I
spend quite a bit of time tuning this stuff and being quite surprised
at the bizarre performance properties of Intel's TLB management
instructions.)
>
> So membarrier code is unchanged (it cares that the serialise is done at
> un-lazy time), core code is simpler (no knowledge of this membarrier
> quirk and it already knows about lazy-tlb so the calls actually improve
> the documentation), and x86 code I would argue becomes nicer (or no real
> difference at worst) because you can move some exit lazy tlb handling to
> that specific call rather than decipher it from switch_mm.
As above, I can't move the exit-lazy handling because the scheduler
doesn't know when I'm unlazying.
>
> >
> > I’m currently trying to document how membarrier actually works, and
> > hopefully this will result in untangling membarrier from mmdrop() and
> > such.
>
> That would be nice.
It's still a work in progress. I haven't actually convinced myself
that the non-IPI case in membarrier() is correct, nor have I convinced
myself that it's incorrect.
Anyway, I think that my patch is a bit incorrect and I either need a
barrier somewhere (which may already exist) or a store-release to
lazy_mm to make sure that all accesses to the lazy mm are done before
lazy_mm is freed. On x86, even aside from the fact that all stores
are releases, this isn't needed -- stopping using an mm is itself a
full barrier. Will this be a performance issue on power?
>
> >
> > A silly part of this is that x86 already has a high quality
> > implementation of most of membarrier(): flush_tlb_mm(). If you flush
> > an mm’s TLB, we carefully propagate the flush to all threads, with
> > attention to memory ordering. We can’t use this directly as an
> > arch-specific implementation of membarrier because it has the annoying
> > side affect of flushing the TLB and because upcoming hardware might be
> > able to flush without guaranteeing a core sync. (Upcoming means Zen
> > 3, but the Zen 3 implementation is sadly not usable by Linux.)
> >
>
> A hardware broadcast TLB flush, you mean? What makes it unusable by
> Linux out of curiosity?
The new instruction is INVLPGB. Unfortunately, x86's ASID field is
very narrow, and there's no way we can give each mm the same ASID
across all CPUs, which means we can't accurately target the flush at
the correct set of TLB entries. I've asked engineers at both Intel
and AMD to widen the ASID field, but that will end up being
complicated -- x86 has run out of bits in its absurdly overloaded CR3
encoding, and widening the ASID to any reasonable size would require
adding a new way to switch mms. There are lots of reasons that x86
should do that anyway [0], but it would be a big project and I'm not
sure that either company is interested in big projects like that.
[0] On x86, you can't switch between (64-bit execution, 48-bit virtual
address space) and (64-bit execution, 57-bit address space) without
exiting 64-bit mode in the middle. This is because the way that the
addressing mode is split among multiple registers prevents a single
instruction from switching between the two states. This is absolutely
delightful for anyone trying to boot an OS on a system with a very,
very large amount of memory.
^ permalink raw reply
* [powerpc:merge] BUILD SUCCESS 9acd775e4579bde0a6d937d72f9669e418aa87ad
From: kernel test robot @ 2020-12-06 2:16 UTC (permalink / raw)
To: Michael Ellerman; +Cc: linuxppc-dev
tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git merge
branch HEAD: 9acd775e4579bde0a6d937d72f9669e418aa87ad Automatic merge of 'master' into merge (2020-12-05 22:54)
elapsed time: 848m
configs tested: 119
configs skipped: 3
The following configs have been built successfully.
More configs may be tested in the coming days.
gcc tested configs:
arm defconfig
arm64 allyesconfig
arm64 defconfig
arm allyesconfig
arm allmodconfig
i386 alldefconfig
powerpc mpc8272_ads_defconfig
powerpc g5_defconfig
powerpc sequoia_defconfig
powerpc gamecube_defconfig
powerpc tqm8555_defconfig
sh se7721_defconfig
mips tb0219_defconfig
sh rsk7269_defconfig
parisc defconfig
sh sh7785lcr_defconfig
arm shmobile_defconfig
um x86_64_defconfig
ia64 tiger_defconfig
arm mv78xx0_defconfig
ia64 zx1_defconfig
sh kfr2r09-romimage_defconfig
mips capcella_defconfig
x86_64 defconfig
mips rbtx49xx_defconfig
arm ixp4xx_defconfig
mips bcm63xx_defconfig
powerpc tqm5200_defconfig
arc haps_hs_defconfig
arm spitz_defconfig
arm exynos_defconfig
arm prima2_defconfig
sh titan_defconfig
powerpc eiger_defconfig
arm trizeps4_defconfig
sh lboxre2_defconfig
sh espt_defconfig
arm vf610m4_defconfig
arm multi_v5_defconfig
arm nhk8815_defconfig
arm sama5_defconfig
powerpc mpc8560_ads_defconfig
ia64 generic_defconfig
arm omap1_defconfig
arm mini2440_defconfig
s390 defconfig
ia64 allmodconfig
ia64 defconfig
ia64 allyesconfig
m68k allmodconfig
m68k defconfig
m68k allyesconfig
nios2 defconfig
arc allyesconfig
nds32 allnoconfig
c6x allyesconfig
nds32 defconfig
nios2 allyesconfig
csky defconfig
alpha defconfig
alpha allyesconfig
xtensa allyesconfig
h8300 allyesconfig
arc defconfig
sh allmodconfig
s390 allyesconfig
parisc allyesconfig
i386 allyesconfig
sparc allyesconfig
sparc defconfig
i386 tinyconfig
i386 defconfig
mips allyesconfig
mips allmodconfig
powerpc allyesconfig
powerpc allmodconfig
powerpc allnoconfig
i386 randconfig-a005-20201205
i386 randconfig-a004-20201205
i386 randconfig-a001-20201205
i386 randconfig-a002-20201205
i386 randconfig-a006-20201205
i386 randconfig-a003-20201205
i386 randconfig-a005-20201204
i386 randconfig-a004-20201204
i386 randconfig-a001-20201204
i386 randconfig-a002-20201204
i386 randconfig-a006-20201204
i386 randconfig-a003-20201204
x86_64 randconfig-a016-20201205
x86_64 randconfig-a012-20201205
x86_64 randconfig-a014-20201205
x86_64 randconfig-a013-20201205
x86_64 randconfig-a015-20201205
x86_64 randconfig-a011-20201205
i386 randconfig-a014-20201205
i386 randconfig-a013-20201205
i386 randconfig-a011-20201205
i386 randconfig-a015-20201205
i386 randconfig-a012-20201205
i386 randconfig-a016-20201205
riscv nommu_k210_defconfig
riscv allyesconfig
riscv nommu_virt_defconfig
riscv allnoconfig
riscv defconfig
riscv rv32_defconfig
riscv allmodconfig
x86_64 rhel
x86_64 allyesconfig
x86_64 rhel-7.6-kselftests
x86_64 rhel-8.3
x86_64 kexec
clang tested configs:
x86_64 randconfig-a004-20201205
x86_64 randconfig-a006-20201205
x86_64 randconfig-a002-20201205
x86_64 randconfig-a001-20201205
x86_64 randconfig-a005-20201205
x86_64 randconfig-a003-20201205
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
^ permalink raw reply
* [powerpc:next-test] BUILD SUCCESS 8817aabb1bdd5811130f94ff6442bb19c9158a3a
From: kernel test robot @ 2020-12-06 2:16 UTC (permalink / raw)
To: Michael Ellerman; +Cc: linuxppc-dev
tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git next-test
branch HEAD: 8817aabb1bdd5811130f94ff6442bb19c9158a3a powerpc: Remove ucache_bsize
elapsed time: 864m
configs tested: 137
configs skipped: 10
The following configs have been built successfully.
More configs may be tested in the coming days.
gcc tested configs:
arm defconfig
arm64 allyesconfig
arm64 defconfig
arm allyesconfig
arm allmodconfig
i386 alldefconfig
powerpc mpc8272_ads_defconfig
powerpc g5_defconfig
powerpc sequoia_defconfig
powerpc gamecube_defconfig
nios2 alldefconfig
arc vdk_hs38_defconfig
powerpc cm5200_defconfig
arm tango4_defconfig
mips decstation_r4k_defconfig
powerpc tqm8555_defconfig
sh se7721_defconfig
c6x evmc6457_defconfig
mips loongson1c_defconfig
powerpc wii_defconfig
mips decstation_64_defconfig
xtensa cadence_csp_defconfig
arm shmobile_defconfig
um x86_64_defconfig
ia64 tiger_defconfig
arm mv78xx0_defconfig
ia64 zx1_defconfig
sh kfr2r09-romimage_defconfig
mips capcella_defconfig
x86_64 defconfig
mips rbtx49xx_defconfig
arm ixp4xx_defconfig
mips bcm63xx_defconfig
powerpc motionpro_defconfig
mips jazz_defconfig
powerpc cell_defconfig
ia64 alldefconfig
powerpc tqm5200_defconfig
arc haps_hs_defconfig
arm spitz_defconfig
arm exynos_defconfig
mips tb0219_defconfig
arm prima2_defconfig
sh titan_defconfig
powerpc eiger_defconfig
arm trizeps4_defconfig
sh lboxre2_defconfig
powerpc amigaone_defconfig
powerpc mpc834x_itxgp_defconfig
sparc defconfig
arm spear3xx_defconfig
arm at91_dt_defconfig
powerpc ebony_defconfig
mips tb0226_defconfig
sh espt_defconfig
arm vf610m4_defconfig
arm multi_v5_defconfig
arm nhk8815_defconfig
arm sama5_defconfig
powerpc mpc8560_ads_defconfig
ia64 generic_defconfig
arm omap1_defconfig
arm mini2440_defconfig
s390 defconfig
ia64 allmodconfig
ia64 defconfig
ia64 allyesconfig
m68k allmodconfig
m68k defconfig
m68k allyesconfig
nios2 defconfig
arc allyesconfig
nds32 allnoconfig
c6x allyesconfig
nds32 defconfig
nios2 allyesconfig
csky defconfig
alpha defconfig
alpha allyesconfig
xtensa allyesconfig
h8300 allyesconfig
arc defconfig
sh allmodconfig
parisc defconfig
s390 allyesconfig
parisc allyesconfig
i386 allyesconfig
sparc allyesconfig
i386 tinyconfig
i386 defconfig
mips allyesconfig
mips allmodconfig
powerpc allyesconfig
powerpc allmodconfig
powerpc allnoconfig
i386 randconfig-a005-20201205
i386 randconfig-a004-20201205
i386 randconfig-a001-20201205
i386 randconfig-a002-20201205
i386 randconfig-a006-20201205
i386 randconfig-a003-20201205
i386 randconfig-a005-20201204
i386 randconfig-a004-20201204
i386 randconfig-a001-20201204
i386 randconfig-a002-20201204
i386 randconfig-a006-20201204
i386 randconfig-a003-20201204
x86_64 randconfig-a016-20201205
x86_64 randconfig-a012-20201205
x86_64 randconfig-a014-20201205
x86_64 randconfig-a013-20201205
x86_64 randconfig-a015-20201205
x86_64 randconfig-a011-20201205
i386 randconfig-a014-20201205
i386 randconfig-a013-20201205
i386 randconfig-a011-20201205
i386 randconfig-a015-20201205
i386 randconfig-a012-20201205
i386 randconfig-a016-20201205
riscv nommu_k210_defconfig
riscv allyesconfig
riscv nommu_virt_defconfig
riscv allnoconfig
riscv defconfig
riscv rv32_defconfig
riscv allmodconfig
x86_64 rhel
x86_64 allyesconfig
x86_64 rhel-7.6-kselftests
x86_64 rhel-8.3
x86_64 kexec
clang tested configs:
x86_64 randconfig-a004-20201205
x86_64 randconfig-a006-20201205
x86_64 randconfig-a002-20201205
x86_64 randconfig-a001-20201205
x86_64 randconfig-a005-20201205
x86_64 randconfig-a003-20201205
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox