Skip to content

Commit e707275

Browse files
vladimirolteankuba-moo
authored andcommitted
net: dpaa: eliminate NR_CPUS dependency in egress_fqs[] and conf_fqs[]
The driver uses the DPAA_TC_TXQ_NUM and DPAA_ETH_TXQ_NUM macros for TX queue handling, and they depend on CONFIG_NR_CPUS. In generic .config files, these can go to very large (8096 CPUs) values for the systems that DPAA1 is integrated in (1-24 CPUs). We allocate a lot of resources that will never be used. Those are: - system memory - QMan FQIDs as managed by qman_alloc_fqid_range(). This is especially painful since currently, when booting with CONFIG_NR_CPUS=8096, a LS1046A-RDB system will only manage to probe 3 of its 6 interfaces. The rest will run out of FQD ("/reserved-memory/qman-fqd" in the device tree) and fail at the qman_create_fq() stage of the probing process. - netdev queues as alloc_etherdev_mq() argument. The high queue indices are simply hidden from the network stack after the call to netif_set_real_num_tx_queues(). With just a tiny bit more effort, we can replace the NR_CPUS compile-time constant with the num_possible_cpus() run-time constant, and dynamically allocate the egress_fqs[] and conf_fqs[] arrays. Even on a system with a high CONFIG_NR_CPUS, num_possible_cpus() will remain equal to the number of available cores on the SoC. The replacement is as follows: - DPAA_TC_TXQ_NUM -> dpaa_num_txqs_per_tc() - DPAA_ETH_TXQ_NUM -> dpaa_max_num_txqs() Signed-off-by: Vladimir Oltean <[email protected]> Acked-by: Madalin Bucur <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 555a05d commit e707275

File tree

2 files changed

+47
-20
lines changed

2 files changed

+47
-20
lines changed

drivers/net/ethernet/freescale/dpaa/dpaa_eth.c

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,7 @@ static int dpaa_setup_tc(struct net_device *net_dev, enum tc_setup_type type,
371371
void *type_data)
372372
{
373373
struct dpaa_priv *priv = netdev_priv(net_dev);
374+
int num_txqs_per_tc = dpaa_num_txqs_per_tc();
374375
struct tc_mqprio_qopt *mqprio = type_data;
375376
u8 num_tc;
376377
int i;
@@ -398,12 +399,12 @@ static int dpaa_setup_tc(struct net_device *net_dev, enum tc_setup_type type,
398399
netdev_set_num_tc(net_dev, num_tc);
399400

400401
for (i = 0; i < num_tc; i++)
401-
netdev_set_tc_queue(net_dev, i, DPAA_TC_TXQ_NUM,
402-
i * DPAA_TC_TXQ_NUM);
402+
netdev_set_tc_queue(net_dev, i, num_txqs_per_tc,
403+
i * num_txqs_per_tc);
403404

404405
out:
405406
priv->num_tc = num_tc ? : 1;
406-
netif_set_real_num_tx_queues(net_dev, priv->num_tc * DPAA_TC_TXQ_NUM);
407+
netif_set_real_num_tx_queues(net_dev, priv->num_tc * num_txqs_per_tc);
407408
return 0;
408409
}
409410

@@ -649,7 +650,7 @@ static inline void dpaa_assign_wq(struct dpaa_fq *fq, int idx)
649650
fq->wq = 6;
650651
break;
651652
case FQ_TYPE_TX:
652-
switch (idx / DPAA_TC_TXQ_NUM) {
653+
switch (idx / dpaa_num_txqs_per_tc()) {
653654
case 0:
654655
/* Low priority (best effort) */
655656
fq->wq = 6;
@@ -667,8 +668,8 @@ static inline void dpaa_assign_wq(struct dpaa_fq *fq, int idx)
667668
fq->wq = 0;
668669
break;
669670
default:
670-
WARN(1, "Too many TX FQs: more than %d!\n",
671-
DPAA_ETH_TXQ_NUM);
671+
WARN(1, "Too many TX FQs: more than %zu!\n",
672+
dpaa_max_num_txqs());
672673
}
673674
break;
674675
default:
@@ -740,7 +741,8 @@ static int dpaa_alloc_all_fqs(struct device *dev, struct list_head *list,
740741

741742
port_fqs->rx_pcdq = &dpaa_fq[0];
742743

743-
if (!dpaa_fq_alloc(dev, 0, DPAA_ETH_TXQ_NUM, list, FQ_TYPE_TX_CONF_MQ))
744+
if (!dpaa_fq_alloc(dev, 0, dpaa_max_num_txqs(), list,
745+
FQ_TYPE_TX_CONF_MQ))
744746
goto fq_alloc_failed;
745747

746748
dpaa_fq = dpaa_fq_alloc(dev, 0, 1, list, FQ_TYPE_TX_ERROR);
@@ -755,7 +757,7 @@ static int dpaa_alloc_all_fqs(struct device *dev, struct list_head *list,
755757

756758
port_fqs->tx_defq = &dpaa_fq[0];
757759

758-
if (!dpaa_fq_alloc(dev, 0, DPAA_ETH_TXQ_NUM, list, FQ_TYPE_TX))
760+
if (!dpaa_fq_alloc(dev, 0, dpaa_max_num_txqs(), list, FQ_TYPE_TX))
759761
goto fq_alloc_failed;
760762

761763
return 0;
@@ -972,7 +974,7 @@ static int dpaa_fq_setup(struct dpaa_priv *priv,
972974
/* If we have more Tx queues than the number of cores,
973975
* just ignore the extra ones.
974976
*/
975-
if (egress_cnt < DPAA_ETH_TXQ_NUM)
977+
if (egress_cnt < dpaa_max_num_txqs())
976978
priv->egress_fqs[egress_cnt++] = &fq->fq_base;
977979
break;
978980
case FQ_TYPE_TX_CONF_MQ:
@@ -992,12 +994,12 @@ static int dpaa_fq_setup(struct dpaa_priv *priv,
992994
}
993995

994996
/* Make sure all CPUs receive a corresponding Tx queue. */
995-
while (egress_cnt < DPAA_ETH_TXQ_NUM) {
997+
while (egress_cnt < dpaa_max_num_txqs()) {
996998
list_for_each_entry(fq, &priv->dpaa_fq_list, list) {
997999
if (fq->fq_type != FQ_TYPE_TX)
9981000
continue;
9991001
priv->egress_fqs[egress_cnt++] = &fq->fq_base;
1000-
if (egress_cnt == DPAA_ETH_TXQ_NUM)
1002+
if (egress_cnt == dpaa_max_num_txqs())
10011003
break;
10021004
}
10031005
}
@@ -1012,7 +1014,7 @@ static inline int dpaa_tx_fq_to_id(const struct dpaa_priv *priv,
10121014
{
10131015
int i;
10141016

1015-
for (i = 0; i < DPAA_ETH_TXQ_NUM; i++)
1017+
for (i = 0; i < dpaa_max_num_txqs(); i++)
10161018
if (priv->egress_fqs[i] == tx_fq)
10171019
return i;
10181020

@@ -3332,7 +3334,7 @@ static int dpaa_eth_probe(struct platform_device *pdev)
33323334
/* Allocate this early, so we can store relevant information in
33333335
* the private area
33343336
*/
3335-
net_dev = alloc_etherdev_mq(sizeof(*priv), DPAA_ETH_TXQ_NUM);
3337+
net_dev = alloc_etherdev_mq(sizeof(*priv), dpaa_max_num_txqs());
33363338
if (!net_dev) {
33373339
dev_err(dev, "alloc_etherdev_mq() failed\n");
33383340
return -ENOMEM;
@@ -3347,6 +3349,22 @@ static int dpaa_eth_probe(struct platform_device *pdev)
33473349

33483350
priv->msg_enable = netif_msg_init(debug, DPAA_MSG_DEFAULT);
33493351

3352+
priv->egress_fqs = devm_kcalloc(dev, dpaa_max_num_txqs(),
3353+
sizeof(*priv->egress_fqs),
3354+
GFP_KERNEL);
3355+
if (!priv->egress_fqs) {
3356+
err = -ENOMEM;
3357+
goto free_netdev;
3358+
}
3359+
3360+
priv->conf_fqs = devm_kcalloc(dev, dpaa_max_num_txqs(),
3361+
sizeof(*priv->conf_fqs),
3362+
GFP_KERNEL);
3363+
if (!priv->conf_fqs) {
3364+
err = -ENOMEM;
3365+
goto free_netdev;
3366+
}
3367+
33503368
mac_dev = dpaa_mac_dev_get(pdev);
33513369
if (IS_ERR(mac_dev)) {
33523370
netdev_err(net_dev, "dpaa_mac_dev_get() failed\n");
@@ -3472,7 +3490,8 @@ static int dpaa_eth_probe(struct platform_device *pdev)
34723490
}
34733491

34743492
priv->num_tc = 1;
3475-
netif_set_real_num_tx_queues(net_dev, priv->num_tc * DPAA_TC_TXQ_NUM);
3493+
netif_set_real_num_tx_queues(net_dev,
3494+
priv->num_tc * dpaa_num_txqs_per_tc());
34763495

34773496
/* Initialize NAPI */
34783497
err = dpaa_napi_add(net_dev);

drivers/net/ethernet/freescale/dpaa/dpaa_eth.h

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,6 @@
1818

1919
/* Number of prioritised traffic classes */
2020
#define DPAA_TC_NUM 4
21-
/* Number of Tx queues per traffic class */
22-
#define DPAA_TC_TXQ_NUM NR_CPUS
23-
/* Total number of Tx queues */
24-
#define DPAA_ETH_TXQ_NUM (DPAA_TC_NUM * DPAA_TC_TXQ_NUM)
2521

2622
/* More detailed FQ types - used for fine-grained WQ assignments */
2723
enum dpaa_fq_type {
@@ -142,8 +138,8 @@ struct dpaa_priv {
142138
struct mac_device *mac_dev;
143139
struct device *rx_dma_dev;
144140
struct device *tx_dma_dev;
145-
struct qman_fq *egress_fqs[DPAA_ETH_TXQ_NUM];
146-
struct qman_fq *conf_fqs[DPAA_ETH_TXQ_NUM];
141+
struct qman_fq **egress_fqs;
142+
struct qman_fq **conf_fqs;
147143

148144
u16 channel;
149145
struct list_head dpaa_fq_list;
@@ -185,4 +181,16 @@ extern const struct ethtool_ops dpaa_ethtool_ops;
185181
/* from dpaa_eth_sysfs.c */
186182
void dpaa_eth_sysfs_remove(struct device *dev);
187183
void dpaa_eth_sysfs_init(struct device *dev);
184+
185+
static inline size_t dpaa_num_txqs_per_tc(void)
186+
{
187+
return num_possible_cpus();
188+
}
189+
190+
/* Total number of Tx queues */
191+
static inline size_t dpaa_max_num_txqs(void)
192+
{
193+
return DPAA_TC_NUM * dpaa_num_txqs_per_tc();
194+
}
195+
188196
#endif /* __DPAA_H */

0 commit comments

Comments
 (0)