.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * CAIF Interface registration. |
---|
3 | 4 | * Copyright (C) ST-Ericsson AB 2010 |
---|
4 | 5 | * Author: Sjur Brendeland |
---|
5 | | - * License terms: GNU General Public License (GPL) version 2 |
---|
6 | 6 | * |
---|
7 | 7 | * Borrowed heavily from file: pn_dev.c. Thanks to Remi Denis-Courmont |
---|
8 | 8 | * and Sakari Ailus <sakari.ailus@nokia.com> |
---|
.. | .. |
---|
112 | 112 | caif_device_list(dev_net(dev)); |
---|
113 | 113 | struct caif_device_entry *caifd; |
---|
114 | 114 | |
---|
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()) { |
---|
116 | 117 | if (caifd->netdev == dev) |
---|
117 | 118 | return caifd; |
---|
118 | 119 | } |
---|
.. | .. |
---|
141 | 142 | |
---|
142 | 143 | spin_lock_bh(&caifd->flow_lock); |
---|
143 | 144 | send_xoff = caifd->xoff; |
---|
144 | | - caifd->xoff = 0; |
---|
| 145 | + caifd->xoff = false; |
---|
145 | 146 | dtor = caifd->xoff_skb_dtor; |
---|
146 | 147 | |
---|
147 | 148 | if (WARN_ON(caifd->xoff_skb != skb)) |
---|
.. | .. |
---|
186 | 187 | goto noxoff; |
---|
187 | 188 | |
---|
188 | 189 | if (likely(!netif_queue_stopped(caifd->netdev))) { |
---|
| 190 | + struct Qdisc *sch; |
---|
| 191 | + |
---|
189 | 192 | /* If we run with a TX queue, check if the queue is too long*/ |
---|
190 | 193 | 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))) |
---|
194 | 196 | goto noxoff; |
---|
195 | 197 | |
---|
| 198 | + /* can check for explicit qdisc len value only !NOLOCK, |
---|
| 199 | + * always set flow off otherwise |
---|
| 200 | + */ |
---|
196 | 201 | 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)) |
---|
198 | 203 | goto noxoff; |
---|
199 | 204 | } |
---|
200 | 205 | |
---|
.. | .. |
---|
215 | 220 | pr_debug("queue has stopped(%d) or is full (%d > %d)\n", |
---|
216 | 221 | netif_queue_stopped(caifd->netdev), |
---|
217 | 222 | qlen, high); |
---|
218 | | - caifd->xoff = 1; |
---|
| 223 | + caifd->xoff = true; |
---|
219 | 224 | caifd->xoff_skb = skb; |
---|
220 | 225 | caifd->xoff_skb_dtor = skb->destructor; |
---|
221 | 226 | skb->destructor = caif_flow_cb; |
---|
.. | .. |
---|
407 | 412 | break; |
---|
408 | 413 | } |
---|
409 | 414 | |
---|
410 | | - caifd->xoff = 0; |
---|
| 415 | + caifd->xoff = false; |
---|
411 | 416 | cfcnfg_set_phy_state(cfg, &caifd->layer, true); |
---|
412 | 417 | rcu_read_unlock(); |
---|
413 | 418 | |
---|
.. | .. |
---|
442 | 447 | if (caifd->xoff_skb_dtor != NULL && caifd->xoff_skb != NULL) |
---|
443 | 448 | caifd->xoff_skb->destructor = caifd->xoff_skb_dtor; |
---|
444 | 449 | |
---|
445 | | - caifd->xoff = 0; |
---|
| 450 | + caifd->xoff = false; |
---|
446 | 451 | caifd->xoff_skb_dtor = NULL; |
---|
447 | 452 | caifd->xoff_skb = NULL; |
---|
448 | 453 | |
---|