Skip to content

Commit 04fb71c

Browse files
Hariprasad Kelamkuba-moo
authored andcommitted
octeontx2-pf: Reuse Transmit queue/Send queue index of HTB class
Real number of Transmit queues are incremented when user enables HTB class and vice versa. Depending on SKB priority driver returns transmit queue (Txq). Transmit queues and Send queues are one-to-one mapped. In few scenarios, Driver is returning transmit queue value which is greater than real number of transmit queue and Stack detects this as error and overwrites transmit queue value. For example user has added two classes and real number of queues are incremented accordingly - tc class add dev eth1 parent 1: classid 1:1 htb rate 100Mbit ceil 100Mbit prio 1 quantum 1024 - tc class add dev eth1 parent 1: classid 1:2 htb rate 100Mbit ceil 200Mbit prio 7 quantum 1024 now if user deletes the class with id 1:1, driver decrements the real number of queues - tc class del dev eth1 classid 1:1 But for the class with id 1:2, driver is returning transmit queue value which is higher than real number of transmit queue leading to below error eth1 selects TX queue x, but real number of TX queues is x This patch solves the problem by assigning deleted class transmit queue/send queue to active class. Signed-off-by: Hariprasad Kelam <[email protected]> Reviewed-by: Simon Horman <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 9c1bbc7 commit 04fb71c

File tree

1 file changed

+79
-1
lines changed
  • drivers/net/ethernet/marvell/octeontx2/nic

1 file changed

+79
-1
lines changed

drivers/net/ethernet/marvell/octeontx2/nic/qos.c

Lines changed: 79 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,20 @@ otx2_qos_sw_create_leaf_node(struct otx2_nic *pfvf,
545545
return node;
546546
}
547547

548+
static struct otx2_qos_node
549+
*otx2_sw_node_find_by_qid(struct otx2_nic *pfvf, u16 qid)
550+
{
551+
struct otx2_qos_node *node = NULL;
552+
int bkt;
553+
554+
hash_for_each(pfvf->qos.qos_hlist, bkt, node, hlist) {
555+
if (node->qid == qid)
556+
break;
557+
}
558+
559+
return node;
560+
}
561+
548562
static struct otx2_qos_node *
549563
otx2_sw_node_find(struct otx2_nic *pfvf, u32 classid)
550564
{
@@ -917,6 +931,7 @@ static void otx2_qos_enadis_sq(struct otx2_nic *pfvf,
917931
otx2_qos_disable_sq(pfvf, qid);
918932

919933
pfvf->qos.qid_to_sqmap[qid] = node->schq;
934+
otx2_qos_txschq_config(pfvf, node);
920935
otx2_qos_enable_sq(pfvf, qid);
921936
}
922937

@@ -1475,13 +1490,45 @@ static int otx2_qos_leaf_to_inner(struct otx2_nic *pfvf, u16 classid,
14751490
return ret;
14761491
}
14771492

1493+
static int otx2_qos_cur_leaf_nodes(struct otx2_nic *pfvf)
1494+
{
1495+
int last = find_last_bit(pfvf->qos.qos_sq_bmap, pfvf->hw.tc_tx_queues);
1496+
1497+
return last == pfvf->hw.tc_tx_queues ? 0 : last + 1;
1498+
}
1499+
1500+
static void otx2_reset_qdisc(struct net_device *dev, u16 qid)
1501+
{
1502+
struct netdev_queue *dev_queue = netdev_get_tx_queue(dev, qid);
1503+
struct Qdisc *qdisc = rtnl_dereference(dev_queue->qdisc_sleeping);
1504+
1505+
if (!qdisc)
1506+
return;
1507+
1508+
spin_lock_bh(qdisc_lock(qdisc));
1509+
qdisc_reset(qdisc);
1510+
spin_unlock_bh(qdisc_lock(qdisc));
1511+
}
1512+
1513+
static void otx2_cfg_smq(struct otx2_nic *pfvf, struct otx2_qos_node *node,
1514+
int qid)
1515+
{
1516+
struct otx2_qos_node *tmp;
1517+
1518+
list_for_each_entry(tmp, &node->child_schq_list, list)
1519+
if (tmp->level == NIX_TXSCH_LVL_MDQ) {
1520+
otx2_qos_txschq_config(pfvf, tmp);
1521+
pfvf->qos.qid_to_sqmap[qid] = tmp->schq;
1522+
}
1523+
}
1524+
14781525
static int otx2_qos_leaf_del(struct otx2_nic *pfvf, u16 *classid,
14791526
struct netlink_ext_ack *extack)
14801527
{
14811528
struct otx2_qos_node *node, *parent;
14821529
int dwrr_del_node = false;
1530+
u16 qid, moved_qid;
14831531
u64 prio;
1484-
u16 qid;
14851532

14861533
netdev_dbg(pfvf->netdev, "TC_HTB_LEAF_DEL classid %04x\n", *classid);
14871534

@@ -1517,6 +1564,37 @@ static int otx2_qos_leaf_del(struct otx2_nic *pfvf, u16 *classid,
15171564
if (!parent->child_static_cnt)
15181565
parent->max_static_prio = 0;
15191566

1567+
moved_qid = otx2_qos_cur_leaf_nodes(pfvf);
1568+
1569+
/* last node just deleted */
1570+
if (moved_qid == 0 || moved_qid == qid)
1571+
return 0;
1572+
1573+
moved_qid--;
1574+
1575+
node = otx2_sw_node_find_by_qid(pfvf, moved_qid);
1576+
if (!node)
1577+
return 0;
1578+
1579+
/* stop traffic to the old queue and disable
1580+
* SQ associated with it
1581+
*/
1582+
node->qid = OTX2_QOS_QID_INNER;
1583+
__clear_bit(moved_qid, pfvf->qos.qos_sq_bmap);
1584+
otx2_qos_disable_sq(pfvf, moved_qid);
1585+
1586+
otx2_reset_qdisc(pfvf->netdev, pfvf->hw.tx_queues + moved_qid);
1587+
1588+
/* enable SQ associated with qid and
1589+
* update the node
1590+
*/
1591+
otx2_cfg_smq(pfvf, node, qid);
1592+
1593+
otx2_qos_enable_sq(pfvf, qid);
1594+
__set_bit(qid, pfvf->qos.qos_sq_bmap);
1595+
node->qid = qid;
1596+
1597+
*classid = node->classid;
15201598
return 0;
15211599
}
15221600

0 commit comments

Comments
 (0)