Commit 6058099d authored by Eric Dumazet's avatar Eric Dumazet Committed by Jakub Kicinski
Browse files

net: remove RTNL use for /proc/sys/net/core/rps_default_mask

parent d8bf56a0
Loading
Loading
Loading
Loading
+12 −3
Original line number Diff line number Diff line
@@ -1210,12 +1210,21 @@ static int rx_queue_default_mask(struct net_device *dev,
				 struct netdev_rx_queue *queue)
{
#if IS_ENABLED(CONFIG_RPS) && IS_ENABLED(CONFIG_SYSCTL)
	struct cpumask *rps_default_mask = READ_ONCE(dev_net(dev)->core.rps_default_mask);
	struct cpumask *rps_default_mask;
	int res = 0;

	mutex_lock(&rps_default_mask_mutex);

	rps_default_mask = dev_net(dev)->core.rps_default_mask;
	if (rps_default_mask && !cpumask_empty(rps_default_mask))
		return netdev_rx_queue_set_rps_mask(queue, rps_default_mask);
#endif
		res = netdev_rx_queue_set_rps_mask(queue, rps_default_mask);

	mutex_unlock(&rps_default_mask_mutex);

	return res;
#else
	return 0;
#endif
}

static int rx_queue_add_kobject(struct net_device *dev, int index)
+2 −0
Original line number Diff line number Diff line
@@ -11,4 +11,6 @@ int netdev_queue_update_kobjects(struct net_device *net,
int netdev_change_owner(struct net_device *, const struct net *net_old,
			const struct net *net_new);

extern struct mutex rps_default_mask_mutex;

#endif
+14 −23
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@
#include <net/rps.h>

#include "dev.h"
#include "net-sysfs.h"

static int int_3600 = 3600;
static int min_sndbuf = SOCK_MIN_SNDBUF;
@@ -96,50 +97,40 @@ static int dump_cpumask(void *buffer, size_t *lenp, loff_t *ppos,

#ifdef CONFIG_RPS

static struct cpumask *rps_default_mask_cow_alloc(struct net *net)
{
	struct cpumask *rps_default_mask;

	if (net->core.rps_default_mask)
		return net->core.rps_default_mask;

	rps_default_mask = kzalloc(cpumask_size(), GFP_KERNEL);
	if (!rps_default_mask)
		return NULL;

	/* pairs with READ_ONCE in rx_queue_default_mask() */
	WRITE_ONCE(net->core.rps_default_mask, rps_default_mask);
	return rps_default_mask;
}
DEFINE_MUTEX(rps_default_mask_mutex);

static int rps_default_mask_sysctl(const struct ctl_table *table, int write,
				   void *buffer, size_t *lenp, loff_t *ppos)
{
	struct net *net = (struct net *)table->data;
	struct cpumask *mask;
	int err = 0;

	rtnl_lock();
	mutex_lock(&rps_default_mask_mutex);
	mask = net->core.rps_default_mask;
	if (write) {
		struct cpumask *rps_default_mask = rps_default_mask_cow_alloc(net);

		if (!mask) {
			mask = kzalloc(cpumask_size(), GFP_KERNEL);
			net->core.rps_default_mask = mask;
		}
		err = -ENOMEM;
		if (!rps_default_mask)
		if (!mask)
			goto done;

		err = cpumask_parse(buffer, rps_default_mask);
		err = cpumask_parse(buffer, mask);
		if (err)
			goto done;

		err = rps_cpumask_housekeeping(rps_default_mask);
		err = rps_cpumask_housekeeping(mask);
		if (err)
			goto done;
	} else {
		err = dump_cpumask(buffer, lenp, ppos,
				   net->core.rps_default_mask ? : cpu_none_mask);
				   mask ?: cpu_none_mask);
	}

done:
	rtnl_unlock();
	mutex_unlock(&rps_default_mask_mutex);
	return err;
}