Skip to content

Commit

Permalink
net: introduce default_rps_mask netns attribute
Browse files Browse the repository at this point in the history
If RPS is enabled, this allows configuring a default rps
mask, which is effective since receive queue creation time.

A default RPS mask allows the system admin to ensure proper
isolation, avoiding races at network namespace or device
creation time.

The default RPS mask is initially empty, and can be
modified via a newly added sysctl entry.

Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Reviewed-by: Simon Horman <simon.horman@corigine.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  • Loading branch information
Paolo Abeni authored and Jakub Kicinski committed Feb 10, 2023
1 parent 370ca71 commit 605cfa1
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 1 deletion.
6 changes: 6 additions & 0 deletions Documentation/admin-guide/sysctl/net.rst
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,12 @@ rmem_max

The maximum receive socket buffer size in bytes.

rps_default_mask
----------------

The default RPS CPU mask used on newly created network devices. An empty
mask means RPS disabled by default.

tstamp_allow_data
-----------------
Allow processes to receive tx timestamps looped together with the original
Expand Down
1 change: 1 addition & 0 deletions include/linux/netdevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ struct net_device_core_stats {
#include <linux/static_key.h>
extern struct static_key_false rps_needed;
extern struct static_key_false rfs_needed;
extern struct cpumask rps_default_mask;
#endif

struct neighbour;
Expand Down
7 changes: 7 additions & 0 deletions net/core/net-sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -1083,6 +1083,13 @@ static int rx_queue_add_kobject(struct net_device *dev, int index)
goto err;
}

#if IS_ENABLED(CONFIG_RPS) && IS_ENABLED(CONFIG_SYSCTL)
if (!cpumask_empty(&rps_default_mask)) {
error = netdev_rx_queue_set_rps_mask(queue, &rps_default_mask);
if (error)
goto err;
}
#endif
kobject_uevent(kobj, KOBJ_ADD);

return error;
Expand Down
37 changes: 36 additions & 1 deletion net/core/sysctl_net_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <linux/vmalloc.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/sched/isolation.h>

#include <net/ip.h>
#include <net/sock.h>
Expand Down Expand Up @@ -45,7 +46,7 @@ EXPORT_SYMBOL(sysctl_fb_tunnels_only_for_init_net);
int sysctl_devconf_inherit_init_net __read_mostly;
EXPORT_SYMBOL(sysctl_devconf_inherit_init_net);

#if IS_ENABLED(CONFIG_NET_FLOW_LIMIT)
#if IS_ENABLED(CONFIG_NET_FLOW_LIMIT) || IS_ENABLED(CONFIG_RPS)
static void dump_cpumask(void *buffer, size_t *lenp, loff_t *ppos,
struct cpumask *mask)
{
Expand Down Expand Up @@ -73,6 +74,31 @@ static void dump_cpumask(void *buffer, size_t *lenp, loff_t *ppos,
#endif

#ifdef CONFIG_RPS
struct cpumask rps_default_mask;

static int rps_default_mask_sysctl(struct ctl_table *table, int write,
void *buffer, size_t *lenp, loff_t *ppos)
{
int err = 0;

rtnl_lock();
if (write) {
err = cpumask_parse(buffer, &rps_default_mask);
if (err)
goto done;

err = rps_cpumask_housekeeping(&rps_default_mask);
if (err)
goto done;
} else {
dump_cpumask(buffer, lenp, ppos, &rps_default_mask);
}

done:
rtnl_unlock();
return err;
}

static int rps_sock_flow_sysctl(struct ctl_table *table, int write,
void *buffer, size_t *lenp, loff_t *ppos)
{
Expand Down Expand Up @@ -482,6 +508,11 @@ static struct ctl_table net_core_table[] = {
.mode = 0644,
.proc_handler = rps_sock_flow_sysctl
},
{
.procname = "rps_default_mask",
.mode = 0644,
.proc_handler = rps_default_mask_sysctl
},
#endif
#ifdef CONFIG_NET_FLOW_LIMIT
{
Expand Down Expand Up @@ -685,6 +716,10 @@ static __net_initdata struct pernet_operations sysctl_core_ops = {

static __init int sysctl_core_init(void)
{
#if IS_ENABLED(CONFIG_RPS)
cpumask_copy(&rps_default_mask, cpu_none_mask);
#endif

register_net_sysctl(&init_net, "net/core", net_core_table);
return register_pernet_subsys(&sysctl_core_ops);
}
Expand Down

0 comments on commit 605cfa1

Please sign in to comment.