hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
kernel/net/caif/caif_dev.c
....@@ -1,8 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * CAIF Interface registration.
34 * Copyright (C) ST-Ericsson AB 2010
45 * Author: Sjur Brendeland
5
- * License terms: GNU General Public License (GPL) version 2
66 *
77 * Borrowed heavily from file: pn_dev.c. Thanks to Remi Denis-Courmont
88 * and Sakari Ailus <sakari.ailus@nokia.com>
....@@ -112,7 +112,8 @@
112112 caif_device_list(dev_net(dev));
113113 struct caif_device_entry *caifd;
114114
115
- list_for_each_entry_rcu(caifd, &caifdevs->list, list) {
115
+ list_for_each_entry_rcu(caifd, &caifdevs->list, list,
116
+ lockdep_rtnl_is_held()) {
116117 if (caifd->netdev == dev)
117118 return caifd;
118119 }
....@@ -141,7 +142,7 @@
141142
142143 spin_lock_bh(&caifd->flow_lock);
143144 send_xoff = caifd->xoff;
144
- caifd->xoff = 0;
145
+ caifd->xoff = false;
145146 dtor = caifd->xoff_skb_dtor;
146147
147148 if (WARN_ON(caifd->xoff_skb != skb))
....@@ -186,15 +187,19 @@
186187 goto noxoff;
187188
188189 if (likely(!netif_queue_stopped(caifd->netdev))) {
190
+ struct Qdisc *sch;
191
+
189192 /* If we run with a TX queue, check if the queue is too long*/
190193 txq = netdev_get_tx_queue(skb->dev, 0);
191
- qlen = qdisc_qlen(rcu_dereference_bh(txq->qdisc));
192
-
193
- if (likely(qlen == 0))
194
+ sch = rcu_dereference_bh(txq->qdisc);
195
+ if (likely(qdisc_is_empty(sch)))
194196 goto noxoff;
195197
198
+ /* can check for explicit qdisc len value only !NOLOCK,
199
+ * always set flow off otherwise
200
+ */
196201 high = (caifd->netdev->tx_queue_len * q_high) / 100;
197
- if (likely(qlen < high))
202
+ if (!(sch->flags & TCQ_F_NOLOCK) && likely(sch->q.qlen < high))
198203 goto noxoff;
199204 }
200205
....@@ -215,7 +220,7 @@
215220 pr_debug("queue has stopped(%d) or is full (%d > %d)\n",
216221 netif_queue_stopped(caifd->netdev),
217222 qlen, high);
218
- caifd->xoff = 1;
223
+ caifd->xoff = true;
219224 caifd->xoff_skb = skb;
220225 caifd->xoff_skb_dtor = skb->destructor;
221226 skb->destructor = caif_flow_cb;
....@@ -407,7 +412,7 @@
407412 break;
408413 }
409414
410
- caifd->xoff = 0;
415
+ caifd->xoff = false;
411416 cfcnfg_set_phy_state(cfg, &caifd->layer, true);
412417 rcu_read_unlock();
413418
....@@ -442,7 +447,7 @@
442447 if (caifd->xoff_skb_dtor != NULL && caifd->xoff_skb != NULL)
443448 caifd->xoff_skb->destructor = caifd->xoff_skb_dtor;
444449
445
- caifd->xoff = 0;
450
+ caifd->xoff = false;
446451 caifd->xoff_skb_dtor = NULL;
447452 caifd->xoff_skb = NULL;
448453