[PATCH net-next 3/3] net: add READ_ONCE()/WRITE_ONCE() annotations for dev->prio_tc_map

Eric Dumazet <[email protected]>
Newsgroups org.kernel.vger.netdev
Message-ID <[email protected]>
Concurrent fast-path readers access dev->prio_tc_map (e.g. via
skb_tx_hash(), netdev_get_prio_tc_map(), and qdiscs) while writers
update entries in dev->prio_tc_map or reset/clear the map via
netdev_reset_tc() and netdev_unbind_sb_channel().

Furthermore, memset() in netdev_reset_tc() and
netdev_unbind_sb_channel() provides no guarantee of performing
atomic word/byte stores.

Add READ_ONCE() and WRITE_ONCE() annotations to netdev_get_prio_tc_map()
and netdev_set_prio_tc_map(), replace memset() in dev.c with explicit
WRITE_ONCE() loops, and update direct array accesses in qdiscs to use
netdev_get_prio_tc_map().

Signed-off-by: Eric Dumazet <[email protected]>
---
 include/linux/netdevice.h  | 4 ++--
 net/core/dev.c             | 6 ++++--
 net/sched/sch_mqprio_lib.c | 3 ++-
 net/sched/sch_taprio.c     | 2 +-
 4 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index db0002bd68f90fa4dd087edabc11549bc8ee0f66..de307c01d33eb8835bdbe32118c2fc086e53a51c 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -2671,7 +2671,7 @@ static inline bool netif_elide_gro(const struct net_device *dev)
 static inline
 int netdev_get_prio_tc_map(const struct net_device *dev, u32 prio)
 {
-	return dev->prio_tc_map[prio & TC_BITMASK];
+	return READ_ONCE(dev->prio_tc_map[prio & TC_BITMASK]);
 }
 
 static inline
@@ -2680,7 +2680,7 @@ int netdev_set_prio_tc_map(struct net_device *dev, u8 prio, u8 tc)
 	if (tc >= READ_ONCE(dev->num_tc))
 		return -EINVAL;
 
-	dev->prio_tc_map[prio & TC_BITMASK] = tc & TC_BITMASK;
+	WRITE_ONCE(dev->prio_tc_map[prio & TC_BITMASK], tc & TC_BITMASK);
 	return 0;
 }
 
diff --git a/net/core/dev.c b/net/core/dev.c
index 8ffae11d272e979bab5b64f4d912d3d97f738d48..d52285ac01a54fdafa63703f1af134e19d028ffd 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -3124,7 +3124,8 @@ void netdev_reset_tc(struct net_device *dev)
 	WRITE_ONCE(dev->num_tc, 0);
 	for (i = 0; i < TC_MAX_QUEUE; i++)
 		WRITE_ONCE(dev->tc_to_txq[i].combined, 0);
-	memset(dev->prio_tc_map, 0, sizeof(dev->prio_tc_map));
+	for (i = 0; i <= TC_BITMASK; i++)
+		WRITE_ONCE(dev->prio_tc_map[i], 0);
 }
 EXPORT_SYMBOL(netdev_reset_tc);
 
@@ -3172,7 +3173,8 @@ void netdev_unbind_sb_channel(struct net_device *dev,
 #endif
 	for (i = 0; i < TC_MAX_QUEUE; i++)
 		WRITE_ONCE(sb_dev->tc_to_txq[i].combined, 0);
-	memset(sb_dev->prio_tc_map, 0, sizeof(sb_dev->prio_tc_map));
+	for (i = 0; i <= TC_BITMASK; i++)
+		WRITE_ONCE(sb_dev->prio_tc_map[i], 0);
 
 	while (txq-- != &dev->_tx[0]) {
 		if (txq->sb_dev == sb_dev)
diff --git a/net/sched/sch_mqprio_lib.c b/net/sched/sch_mqprio_lib.c
index b60e130c70781479eed0ea5a02d01197f03f4895..888935e34d4381f85aaf4c97cf9c4bacb93e13f1 100644
--- a/net/sched/sch_mqprio_lib.c
+++ b/net/sched/sch_mqprio_lib.c
@@ -105,7 +105,8 @@ void mqprio_qopt_reconstruct(struct net_device *dev, struct tc_mqprio_qopt *qopt
 	int tc, num_tc = netdev_get_num_tc(dev);
 
 	qopt->num_tc = num_tc;
-	memcpy(qopt->prio_tc_map, dev->prio_tc_map, sizeof(qopt->prio_tc_map));
+	for (tc = 0; tc <= TC_BITMASK; tc++)
+		qopt->prio_tc_map[tc] = netdev_get_prio_tc_map(dev, tc);
 
 	for (tc = 0; tc < num_tc; tc++) {
 		struct netdev_tc_txq res;
diff --git a/net/sched/sch_taprio.c b/net/sched/sch_taprio.c
index 18fcb4e78456a2f74fa5d3465175d100a39575b4..39ac5b97aa3af83fe63ab5ff9173c39700f6bbb0 100644
--- a/net/sched/sch_taprio.c
+++ b/net/sched/sch_taprio.c
@@ -1813,7 +1813,7 @@ static int taprio_mqprio_cmp(const struct net_device *dev,
 	}
 
 	for (i = 0; i <= TC_BITMASK; i++)
-		if (dev->prio_tc_map[i] != mqprio->prio_tc_map[i])
+		if (netdev_get_prio_tc_map(dev, i) != mqprio->prio_tc_map[i])
 			return -1;
 
 	return 0;
-- 
2.55.0.679.g6767b8d81c-goog
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.