summaryrefslogtreecommitdiff
path: root/include/net
diff options
context:
space:
mode:
authorVlad Buslov <vladbu@mellanox.com>2021-12-10 10:47:27 +0000
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2021-12-14 10:18:04 +0100
commitf602ed9f8574512e7ea1ab65c3db7ba71053bf27 (patch)
treeed454e606d35f221b917385923d18a19d80d17f6 /include/net
parent92833e8b5db6c209e9311ac8c6a44d3bf1856659 (diff)
net: sched: extend Qdisc with rcu
[ Upstream commit 3a7d0d07a386716b459b00783b11a8211cefcc0f ] Currently, Qdisc API functions assume that users have rtnl lock taken. To implement rtnl unlocked classifiers update interface, Qdisc API must be extended with functions that do not require rtnl lock. Extend Qdisc structure with rcu. Implement special version of put function qdisc_put_unlocked() that is called without rtnl lock taken. This function only takes rtnl lock if Qdisc reference counter reached zero and is intended to be used as optimization. Signed-off-by: Vlad Buslov <vladbu@mellanox.com> Acked-by: Jiri Pirko <jiri@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net> [Lee: Sent to Stable] Link: https://syzkaller.appspot.com/bug?id=d7e411c5472dd5da33d8cc921ccadc747743a568 Reported-by: syzbot+5f229e48cccc804062c0@syzkaller.appspotmail.com Signed-off-by: Lee Jones <lee.jones@linaro.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'include/net')
-rw-r--r--include/net/pkt_sched.h1
-rw-r--r--include/net/sch_generic.h2
2 files changed, 3 insertions, 0 deletions
diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h
index edca90ef3bdc..1a6ac924266d 100644
--- a/include/net/pkt_sched.h
+++ b/include/net/pkt_sched.h
@@ -103,6 +103,7 @@ int qdisc_set_default(const char *id);
void qdisc_hash_add(struct Qdisc *q, bool invisible);
void qdisc_hash_del(struct Qdisc *q);
struct Qdisc *qdisc_lookup(struct net_device *dev, u32 handle);
+struct Qdisc *qdisc_lookup_rcu(struct net_device *dev, u32 handle);
struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r,
struct nlattr *tab,
struct netlink_ext_ack *extack);
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index 70dfbd043753..04a5133d875e 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -108,6 +108,7 @@ struct Qdisc {
spinlock_t busylock ____cacheline_aligned_in_smp;
spinlock_t seqlock;
+ struct rcu_head rcu;
};
static inline void qdisc_refcount_inc(struct Qdisc *qdisc)
@@ -560,6 +561,7 @@ struct Qdisc *dev_graft_qdisc(struct netdev_queue *dev_queue,
struct Qdisc *qdisc);
void qdisc_reset(struct Qdisc *qdisc);
void qdisc_put(struct Qdisc *qdisc);
+void qdisc_put_unlocked(struct Qdisc *qdisc);
void qdisc_tree_reduce_backlog(struct Qdisc *qdisc, unsigned int n,
unsigned int len);
struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue,