Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f9eb8aea authored by Eric Dumazet's avatar Eric Dumazet Committed by David S. Miller
Browse files

net_sched: transform qdisc running bit into a seqcount



Instead of using a single bit (__QDISC___STATE_RUNNING)
in sch->__state, use a seqcount.

This adds lockdep support, but more importantly it will allow us
to sample qdisc/class statistics without having to grab qdisc root lock.

Signed-off-by: default avatarEric Dumazet <edumazet@google.com>
Cc: Cong Wang <xiyou.wangcong@gmail.com>
Cc: Jamal Hadi Salim <jhs@mojatatu.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 64151ae3
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -4610,6 +4610,7 @@ static int bond_check_params(struct bond_params *params)
static struct lock_class_key bonding_netdev_xmit_lock_key;
static struct lock_class_key bonding_netdev_addr_lock_key;
static struct lock_class_key bonding_tx_busylock_key;
static struct lock_class_key bonding_qdisc_running_key;

static void bond_set_lockdep_class_one(struct net_device *dev,
				       struct netdev_queue *txq,
@@ -4625,6 +4626,7 @@ static void bond_set_lockdep_class(struct net_device *dev)
			  &bonding_netdev_addr_lock_key);
	netdev_for_each_tx_queue(dev, bond_set_lockdep_class_one, NULL);
	dev->qdisc_tx_busylock = &bonding_tx_busylock_key;
	dev->qdisc_running_key = &bonding_qdisc_running_key;
}

/* Called from registration process */
+3 −0
Original line number Diff line number Diff line
@@ -1313,9 +1313,12 @@ ppp_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats64)
}

static struct lock_class_key ppp_tx_busylock;
static struct lock_class_key ppp_qdisc_running_key;

static int ppp_dev_init(struct net_device *dev)
{
	dev->qdisc_tx_busylock = &ppp_tx_busylock;
	dev->qdisc_running_key = &ppp_qdisc_running_key;
	return 0;
}

+2 −0
Original line number Diff line number Diff line
@@ -1577,6 +1577,7 @@ static const struct team_option team_options[] = {
static struct lock_class_key team_netdev_xmit_lock_key;
static struct lock_class_key team_netdev_addr_lock_key;
static struct lock_class_key team_tx_busylock_key;
static struct lock_class_key team_qdisc_running_key;

static void team_set_lockdep_class_one(struct net_device *dev,
				       struct netdev_queue *txq,
@@ -1590,6 +1591,7 @@ static void team_set_lockdep_class(struct net_device *dev)
	lockdep_set_class(&dev->addr_list_lock, &team_netdev_addr_lock_key);
	netdev_for_each_tx_queue(dev, team_set_lockdep_class_one, NULL);
	dev->qdisc_tx_busylock = &team_tx_busylock_key;
	dev->qdisc_running_key = &team_qdisc_running_key;
}

static int team_init(struct net_device *dev)
+1 −0
Original line number Diff line number Diff line
@@ -1862,6 +1862,7 @@ struct net_device {
#endif
	struct phy_device	*phydev;
	struct lock_class_key	*qdisc_tx_busylock;
	struct lock_class_key	*qdisc_running_key;
	bool			proto_down;
};
#define to_net_dev(d) container_of(d, struct net_device, dev)
+4 −11
Original line number Diff line number Diff line
@@ -29,13 +29,6 @@ enum qdisc_state_t {
	__QDISC_STATE_THROTTLED,
};

/*
 * following bits are only changed while qdisc lock is held
 */
enum qdisc___state_t {
	__QDISC___STATE_RUNNING = 1,
};

struct qdisc_size_table {
	struct rcu_head		rcu;
	struct list_head	list;
@@ -93,7 +86,7 @@ struct Qdisc {
	unsigned long		state;
	struct sk_buff_head	q;
	struct gnet_stats_basic_packed bstats;
	unsigned int		__state;
	seqcount_t		running;
	struct gnet_stats_queue	qstats;
	struct rcu_head		rcu_head;
	int			padded;
@@ -104,20 +97,20 @@ struct Qdisc {

static inline bool qdisc_is_running(const struct Qdisc *qdisc)
{
	return (qdisc->__state & __QDISC___STATE_RUNNING) ? true : false;
	return (raw_read_seqcount(&qdisc->running) & 1) ? true : false;
}

static inline bool qdisc_run_begin(struct Qdisc *qdisc)
{
	if (qdisc_is_running(qdisc))
		return false;
	qdisc->__state |= __QDISC___STATE_RUNNING;
	write_seqcount_begin(&qdisc->running);
	return true;
}

static inline void qdisc_run_end(struct Qdisc *qdisc)
{
	qdisc->__state &= ~__QDISC___STATE_RUNNING;
	write_seqcount_end(&qdisc->running);
}

static inline bool qdisc_may_bulk(const struct Qdisc *qdisc)
Loading