Skip to content

Commit 38d711a

Browse files
committed
Merge branch 'default_rps_mask-follow-up'
Paolo Abeni says: ==================== net: default_rps_mask follow-up The first patch namespacify the setting. In the common case, once proper isolation is in place in the main namespace, forwarding to/from each child netns will allways happen on the desidered CPUs. Any additional RPS stage inside the child namespace will not provide additional isolation and could hurt performance badly if picking a CPU on a remote node. The 2nd patch adds more self-tests coverage. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents e469b62 + 3a7d84e commit 38d711a

File tree

5 files changed

+88
-33
lines changed

5 files changed

+88
-33
lines changed

include/linux/netdevice.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,6 @@ struct net_device_core_stats {
224224
#include <linux/static_key.h>
225225
extern struct static_key_false rps_needed;
226226
extern struct static_key_false rfs_needed;
227-
extern struct cpumask rps_default_mask;
228227
#endif
229228

230229
struct neighbour;

include/net/netns/core.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
struct ctl_table_header;
88
struct prot_inuse;
9+
struct cpumask;
910

1011
struct netns_core {
1112
/* core sysctls */
@@ -17,6 +18,10 @@ struct netns_core {
1718
#ifdef CONFIG_PROC_FS
1819
struct prot_inuse __percpu *prot_inuse;
1920
#endif
21+
22+
#if IS_ENABLED(CONFIG_RPS) && IS_ENABLED(CONFIG_SYSCTL)
23+
struct cpumask *rps_default_mask;
24+
#endif
2025
};
2126

2227
#endif

net/core/net-sysfs.c

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1060,6 +1060,18 @@ static const struct kobj_type rx_queue_ktype = {
10601060
.get_ownership = rx_queue_get_ownership,
10611061
};
10621062

1063+
static int rx_queue_default_mask(struct net_device *dev,
1064+
struct netdev_rx_queue *queue)
1065+
{
1066+
#if IS_ENABLED(CONFIG_RPS) && IS_ENABLED(CONFIG_SYSCTL)
1067+
struct cpumask *rps_default_mask = READ_ONCE(dev_net(dev)->core.rps_default_mask);
1068+
1069+
if (rps_default_mask && !cpumask_empty(rps_default_mask))
1070+
return netdev_rx_queue_set_rps_mask(queue, rps_default_mask);
1071+
#endif
1072+
return 0;
1073+
}
1074+
10631075
static int rx_queue_add_kobject(struct net_device *dev, int index)
10641076
{
10651077
struct netdev_rx_queue *queue = dev->_rx + index;
@@ -1083,13 +1095,10 @@ static int rx_queue_add_kobject(struct net_device *dev, int index)
10831095
goto err;
10841096
}
10851097

1086-
#if IS_ENABLED(CONFIG_RPS) && IS_ENABLED(CONFIG_SYSCTL)
1087-
if (!cpumask_empty(&rps_default_mask)) {
1088-
error = netdev_rx_queue_set_rps_mask(queue, &rps_default_mask);
1089-
if (error)
1090-
goto err;
1091-
}
1092-
#endif
1098+
error = rx_queue_default_mask(dev, queue);
1099+
if (error)
1100+
goto err;
1101+
10931102
kobject_uevent(kobj, KOBJ_ADD);
10941103

10951104
return error;

net/core/sysctl_net_core.c

Lines changed: 38 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -74,24 +74,47 @@ static void dump_cpumask(void *buffer, size_t *lenp, loff_t *ppos,
7474
#endif
7575

7676
#ifdef CONFIG_RPS
77-
struct cpumask rps_default_mask;
77+
78+
static struct cpumask *rps_default_mask_cow_alloc(struct net *net)
79+
{
80+
struct cpumask *rps_default_mask;
81+
82+
if (net->core.rps_default_mask)
83+
return net->core.rps_default_mask;
84+
85+
rps_default_mask = kzalloc(cpumask_size(), GFP_KERNEL);
86+
if (!rps_default_mask)
87+
return NULL;
88+
89+
/* pairs with READ_ONCE in rx_queue_default_mask() */
90+
WRITE_ONCE(net->core.rps_default_mask, rps_default_mask);
91+
return rps_default_mask;
92+
}
7893

7994
static int rps_default_mask_sysctl(struct ctl_table *table, int write,
8095
void *buffer, size_t *lenp, loff_t *ppos)
8196
{
97+
struct net *net = (struct net *)table->data;
8298
int err = 0;
8399

84100
rtnl_lock();
85101
if (write) {
86-
err = cpumask_parse(buffer, &rps_default_mask);
102+
struct cpumask *rps_default_mask = rps_default_mask_cow_alloc(net);
103+
104+
err = -ENOMEM;
105+
if (!rps_default_mask)
106+
goto done;
107+
108+
err = cpumask_parse(buffer, rps_default_mask);
87109
if (err)
88110
goto done;
89111

90-
err = rps_cpumask_housekeeping(&rps_default_mask);
112+
err = rps_cpumask_housekeeping(rps_default_mask);
91113
if (err)
92114
goto done;
93115
} else {
94-
dump_cpumask(buffer, lenp, ppos, &rps_default_mask);
116+
dump_cpumask(buffer, lenp, ppos,
117+
net->core.rps_default_mask ? : cpu_none_mask);
95118
}
96119

97120
done:
@@ -508,11 +531,6 @@ static struct ctl_table net_core_table[] = {
508531
.mode = 0644,
509532
.proc_handler = rps_sock_flow_sysctl
510533
},
511-
{
512-
.procname = "rps_default_mask",
513-
.mode = 0644,
514-
.proc_handler = rps_default_mask_sysctl
515-
},
516534
#endif
517535
#ifdef CONFIG_NET_FLOW_LIMIT
518536
{
@@ -639,6 +657,14 @@ static struct ctl_table net_core_table[] = {
639657
};
640658

641659
static struct ctl_table netns_core_table[] = {
660+
#if IS_ENABLED(CONFIG_RPS)
661+
{
662+
.procname = "rps_default_mask",
663+
.data = &init_net,
664+
.mode = 0644,
665+
.proc_handler = rps_default_mask_sysctl
666+
},
667+
#endif
642668
{
643669
.procname = "somaxconn",
644670
.data = &init_net.core.sysctl_somaxconn,
@@ -706,6 +732,9 @@ static __net_exit void sysctl_core_net_exit(struct net *net)
706732
tbl = net->core.sysctl_hdr->ctl_table_arg;
707733
unregister_net_sysctl_table(net->core.sysctl_hdr);
708734
BUG_ON(tbl == netns_core_table);
735+
#if IS_ENABLED(CONFIG_RPS)
736+
kfree(net->core.rps_default_mask);
737+
#endif
709738
kfree(tbl);
710739
}
711740

@@ -716,10 +745,6 @@ static __net_initdata struct pernet_operations sysctl_core_ops = {
716745

717746
static __init int sysctl_core_init(void)
718747
{
719-
#if IS_ENABLED(CONFIG_RPS)
720-
cpumask_copy(&rps_default_mask, cpu_none_mask);
721-
#endif
722-
723748
register_net_sysctl(&init_net, "net/core", net_core_table);
724749
return register_pernet_subsys(&sysctl_core_ops);
725750
}

tools/testing/selftests/net/rps_default_mask.sh

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ ret=0
88
[ $cpus -gt 2 ] || exit $ksft_skip
99

1010
readonly INITIAL_RPS_DEFAULT_MASK=$(cat /proc/sys/net/core/rps_default_mask)
11-
readonly NETNS="ns-$(mktemp -u XXXXXX)"
11+
readonly TAG="$(mktemp -u XXXXXX)"
12+
readonly VETH="veth${TAG}"
13+
readonly NETNS="ns-${TAG}"
1214

1315
setup() {
1416
ip netns add "${NETNS}"
@@ -21,11 +23,15 @@ cleanup() {
2123
}
2224

2325
chk_rps() {
24-
local rps_mask expected_rps_mask=$3
25-
local dev_name=$2
26+
local rps_mask expected_rps_mask=$4
27+
local dev_name=$3
28+
local netns=$2
29+
local cmd="cat"
2630
local msg=$1
2731

28-
rps_mask=$(ip netns exec $NETNS cat /sys/class/net/$dev_name/queues/rx-0/rps_cpus)
32+
[ -n "$netns" ] && cmd="ip netns exec $netns $cmd"
33+
34+
rps_mask=$($cmd /sys/class/net/$dev_name/queues/rx-0/rps_cpus)
2935
printf "%-60s" "$msg"
3036
if [ $rps_mask -eq $expected_rps_mask ]; then
3137
echo "[ ok ]"
@@ -39,19 +45,30 @@ trap cleanup EXIT
3945

4046
echo 0 > /proc/sys/net/core/rps_default_mask
4147
setup
42-
chk_rps "empty rps_default_mask" lo 0
48+
chk_rps "empty rps_default_mask" $NETNS lo 0
4349
cleanup
4450

4551
echo 1 > /proc/sys/net/core/rps_default_mask
4652
setup
47-
chk_rps "non zero rps_default_mask" lo 1
53+
chk_rps "changing rps_default_mask dont affect existing devices" "" lo $INITIAL_RPS_DEFAULT_MASK
4854

4955
echo 3 > /proc/sys/net/core/rps_default_mask
50-
chk_rps "changing rps_default_mask dont affect existing netns" lo 1
56+
chk_rps "changing rps_default_mask dont affect existing netns" $NETNS lo 0
57+
58+
ip link add name $VETH type veth peer netns $NETNS name $VETH
59+
ip link set dev $VETH up
60+
ip -n $NETNS link set dev $VETH up
61+
chk_rps "changing rps_default_mask affect newly created devices" "" $VETH 3
62+
chk_rps "changing rps_default_mask don't affect newly child netns[II]" $NETNS $VETH 0
63+
ip netns del $NETNS
64+
65+
setup
66+
chk_rps "rps_default_mask is 0 by default in child netns" "$NETNS" lo 0
67+
68+
ip netns exec $NETNS sysctl -qw net.core.rps_default_mask=1
69+
ip link add name $VETH type veth peer netns $NETNS name $VETH
70+
chk_rps "changing rps_default_mask in child ns don't affect the main one" "" lo $INITIAL_RPS_DEFAULT_MASK
71+
chk_rps "changing rps_default_mask in child ns affects new childns devices" $NETNS $VETH 1
72+
chk_rps "changing rps_default_mask in child ns don't affect existing devices" $NETNS lo 0
5173

52-
ip -n $NETNS link add type veth
53-
ip -n $NETNS link set dev veth0 up
54-
ip -n $NETNS link set dev veth1 up
55-
chk_rps "changing rps_default_mask affect newly created devices" veth0 3
56-
chk_rps "changing rps_default_mask affect newly created devices[II]" veth1 3
5774
exit $ret

0 commit comments

Comments
 (0)