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

rps: add __rcu annotations



Add __rcu annotations to :
	(struct netdev_rx_queue)->rps_map
	(struct netdev_rx_queue)->rps_flow_table
	struct rps_sock_flow_table *rps_sock_flow_table;

And use appropriate rcu primitives.

Signed-off-by: default avatarEric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent f6318e55
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -585,12 +585,12 @@ static inline void rps_reset_sock_flow(struct rps_sock_flow_table *table,
		table->ents[hash & table->mask] = RPS_NO_CPU;
}

extern struct rps_sock_flow_table *rps_sock_flow_table;
extern struct rps_sock_flow_table __rcu *rps_sock_flow_table;

/* This structure contains an instance of an RX queue. */
struct netdev_rx_queue {
	struct rps_map *rps_map;
	struct rps_dev_flow_table *rps_flow_table;
	struct rps_map __rcu		*rps_map;
	struct rps_dev_flow_table __rcu	*rps_flow_table;
	struct kobject			kobj;
	struct netdev_rx_queue		*first;
	atomic_t			count;
+6 −6
Original line number Diff line number Diff line
@@ -2413,7 +2413,7 @@ EXPORT_SYMBOL(__skb_get_rxhash);
#ifdef CONFIG_RPS

/* One global table that all flow-based protocols share. */
struct rps_sock_flow_table *rps_sock_flow_table __read_mostly;
struct rps_sock_flow_table __rcu *rps_sock_flow_table __read_mostly;
EXPORT_SYMBOL(rps_sock_flow_table);

/*
@@ -2425,7 +2425,7 @@ static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb,
		       struct rps_dev_flow **rflowp)
{
	struct netdev_rx_queue *rxqueue;
	struct rps_map *map = NULL;
	struct rps_map *map;
	struct rps_dev_flow_table *flow_table;
	struct rps_sock_flow_table *sock_flow_table;
	int cpu = -1;
@@ -2444,15 +2444,15 @@ static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb,
	} else
		rxqueue = dev->_rx;

	if (rxqueue->rps_map) {
	map = rcu_dereference(rxqueue->rps_map);
		if (map && map->len == 1) {
	if (map) {
		if (map->len == 1) {
			tcpu = map->cpus[0];
			if (cpu_online(tcpu))
				cpu = tcpu;
			goto done;
		}
	} else if (!rxqueue->rps_flow_table) {
	} else if (!rcu_dereference_raw(rxqueue->rps_flow_table)) {
		goto done;
	}

+13 −7
Original line number Diff line number Diff line
@@ -598,7 +598,8 @@ static ssize_t store_rps_map(struct netdev_rx_queue *queue,
	}

	spin_lock(&rps_map_lock);
	old_map = queue->rps_map;
	old_map = rcu_dereference_protected(queue->rps_map,
					    lockdep_is_held(&rps_map_lock));
	rcu_assign_pointer(queue->rps_map, map);
	spin_unlock(&rps_map_lock);

@@ -677,7 +678,8 @@ static ssize_t store_rps_dev_flow_table_cnt(struct netdev_rx_queue *queue,
		table = NULL;

	spin_lock(&rps_dev_flow_lock);
	old_table = queue->rps_flow_table;
	old_table = rcu_dereference_protected(queue->rps_flow_table,
					      lockdep_is_held(&rps_dev_flow_lock));
	rcu_assign_pointer(queue->rps_flow_table, table);
	spin_unlock(&rps_dev_flow_lock);

@@ -705,13 +707,17 @@ static void rx_queue_release(struct kobject *kobj)
{
	struct netdev_rx_queue *queue = to_rx_queue(kobj);
	struct netdev_rx_queue *first = queue->first;
	struct rps_map *map;
	struct rps_dev_flow_table *flow_table;

	if (queue->rps_map)
		call_rcu(&queue->rps_map->rcu, rps_map_release);

	if (queue->rps_flow_table)
		call_rcu(&queue->rps_flow_table->rcu,
		    rps_dev_flow_table_release);
	map = rcu_dereference_raw(queue->rps_map);
	if (map)
		call_rcu(&map->rcu, rps_map_release);

	flow_table = rcu_dereference_raw(queue->rps_flow_table);
	if (flow_table)
		call_rcu(&flow_table->rcu, rps_dev_flow_table_release);

	if (atomic_dec_and_test(&first->count))
		kfree(first);
+2 −1
Original line number Diff line number Diff line
@@ -34,7 +34,8 @@ static int rps_sock_flow_sysctl(ctl_table *table, int write,

	mutex_lock(&sock_flow_mutex);

	orig_sock_table = rps_sock_flow_table;
	orig_sock_table = rcu_dereference_protected(rps_sock_flow_table,
					lockdep_is_held(&sock_flow_mutex));
	size = orig_size = orig_sock_table ? orig_sock_table->mask + 1 : 0;

	ret = proc_dointvec(&tmp, write, buffer, lenp, ppos);