Skip to content

Commit 66dfb58

Browse files
gal-pressmanNipaLocal
authored and
NipaLocal
committed
Revert "openvswitch: Merge three per-CPU structures into one"
This reverts commit 035fcdc. The cited commit changed openvswitch to use static percpu allocations, and exhausted the reserved chunk on module init. Allocation of struct ovs_pcpu_storage (6488 bytes) fails on ARM: percpu: allocation failed, size=6488 align=8 atomic=0, alloc from reserved chunk failed CPU: 2 UID: 0 PID: 4571 Comm: modprobe Not tainted 6.15.0-for-upstream-bluefield-2025-05-28-15-45 #1 NONE Hardware name: https://www.mellanox.com BlueField SoC/BlueField SoC, BIOS 4.9.0.13378 Oct 30 2024 Call trace: show_stack+0x20/0x38 (C) dump_stack_lvl+0x80/0xf8 dump_stack+0x18/0x28 pcpu_alloc_noprof+0x860/0xa48 load_module+0xc68/0x23f0 init_module_from_file+0x90/0xe0 __arm64_sys_finit_module+0x21c/0x3d8 invoke_syscall+0x50/0x120 el0_svc_common.constprop.0+0x48/0xf0 do_el0_svc+0x24/0x38 el0_svc+0x34/0xf0 el0t_64_sync_handler+0x10c/0x138 el0t_64_sync+0x1ac/0x1b0 openvswitch: Could not allocate 6488 bytes percpu data For large buffers, dynamic allocations are preferred, revert the patch. Cc: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Signed-off-by: Gal Pressman <gal@nvidia.com> Signed-off-by: NipaLocal <nipa@local>
1 parent 85c159f commit 66dfb58

File tree

3 files changed

+44
-17
lines changed

3 files changed

+44
-17
lines changed

net/openvswitch/actions.c

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -78,22 +78,17 @@ struct action_flow_keys {
7878
struct sw_flow_key key[OVS_DEFERRED_ACTION_THRESHOLD];
7979
};
8080

81-
struct ovs_pcpu_storage {
82-
struct action_fifo action_fifos;
83-
struct action_flow_keys flow_keys;
84-
int exec_level;
85-
};
86-
87-
static DEFINE_PER_CPU(struct ovs_pcpu_storage, ovs_pcpu_storage);
81+
static struct action_fifo __percpu *action_fifos;
82+
static struct action_flow_keys __percpu *flow_keys;
83+
static DEFINE_PER_CPU(int, exec_actions_level);
8884

8985
/* Make a clone of the 'key', using the pre-allocated percpu 'flow_keys'
9086
* space. Return NULL if out of key spaces.
9187
*/
9288
static struct sw_flow_key *clone_key(const struct sw_flow_key *key_)
9389
{
94-
struct ovs_pcpu_storage *ovs_pcpu = this_cpu_ptr(&ovs_pcpu_storage);
95-
struct action_flow_keys *keys = &ovs_pcpu->flow_keys;
96-
int level = ovs_pcpu->exec_level;
90+
struct action_flow_keys *keys = this_cpu_ptr(flow_keys);
91+
int level = this_cpu_read(exec_actions_level);
9792
struct sw_flow_key *key = NULL;
9893

9994
if (level <= OVS_DEFERRED_ACTION_THRESHOLD) {
@@ -137,9 +132,10 @@ static struct deferred_action *add_deferred_actions(struct sk_buff *skb,
137132
const struct nlattr *actions,
138133
const int actions_len)
139134
{
140-
struct action_fifo *fifo = this_cpu_ptr(&ovs_pcpu_storage.action_fifos);
135+
struct action_fifo *fifo;
141136
struct deferred_action *da;
142137

138+
fifo = this_cpu_ptr(action_fifos);
143139
da = action_fifo_put(fifo);
144140
if (da) {
145141
da->skb = skb;
@@ -1612,13 +1608,13 @@ static int clone_execute(struct datapath *dp, struct sk_buff *skb,
16121608

16131609
if (actions) { /* Sample action */
16141610
if (clone_flow_key)
1615-
__this_cpu_inc(ovs_pcpu_storage.exec_level);
1611+
__this_cpu_inc(exec_actions_level);
16161612

16171613
err = do_execute_actions(dp, skb, clone,
16181614
actions, len);
16191615

16201616
if (clone_flow_key)
1621-
__this_cpu_dec(ovs_pcpu_storage.exec_level);
1617+
__this_cpu_dec(exec_actions_level);
16221618
} else { /* Recirc action */
16231619
clone->recirc_id = recirc_id;
16241620
ovs_dp_process_packet(skb, clone);
@@ -1654,7 +1650,7 @@ static int clone_execute(struct datapath *dp, struct sk_buff *skb,
16541650

16551651
static void process_deferred_actions(struct datapath *dp)
16561652
{
1657-
struct action_fifo *fifo = this_cpu_ptr(&ovs_pcpu_storage.action_fifos);
1653+
struct action_fifo *fifo = this_cpu_ptr(action_fifos);
16581654

16591655
/* Do not touch the FIFO in case there is no deferred actions. */
16601656
if (action_fifo_is_empty(fifo))
@@ -1685,7 +1681,7 @@ int ovs_execute_actions(struct datapath *dp, struct sk_buff *skb,
16851681
{
16861682
int err, level;
16871683

1688-
level = __this_cpu_inc_return(ovs_pcpu_storage.exec_level);
1684+
level = __this_cpu_inc_return(exec_actions_level);
16891685
if (unlikely(level > OVS_RECURSION_LIMIT)) {
16901686
net_crit_ratelimited("ovs: recursion limit reached on datapath %s, probable configuration error\n",
16911687
ovs_dp_name(dp));
@@ -1702,6 +1698,27 @@ int ovs_execute_actions(struct datapath *dp, struct sk_buff *skb,
17021698
process_deferred_actions(dp);
17031699

17041700
out:
1705-
__this_cpu_dec(ovs_pcpu_storage.exec_level);
1701+
__this_cpu_dec(exec_actions_level);
17061702
return err;
17071703
}
1704+
1705+
int action_fifos_init(void)
1706+
{
1707+
action_fifos = alloc_percpu(struct action_fifo);
1708+
if (!action_fifos)
1709+
return -ENOMEM;
1710+
1711+
flow_keys = alloc_percpu(struct action_flow_keys);
1712+
if (!flow_keys) {
1713+
free_percpu(action_fifos);
1714+
return -ENOMEM;
1715+
}
1716+
1717+
return 0;
1718+
}
1719+
1720+
void action_fifos_exit(void)
1721+
{
1722+
free_percpu(action_fifos);
1723+
free_percpu(flow_keys);
1724+
}

net/openvswitch/datapath.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2729,10 +2729,14 @@ static int __init dp_init(void)
27292729

27302730
pr_info("Open vSwitch switching datapath\n");
27312731

2732-
err = ovs_internal_dev_rtnl_link_register();
2732+
err = action_fifos_init();
27332733
if (err)
27342734
goto error;
27352735

2736+
err = ovs_internal_dev_rtnl_link_register();
2737+
if (err)
2738+
goto error_action_fifos_exit;
2739+
27362740
err = ovs_flow_init();
27372741
if (err)
27382742
goto error_unreg_rtnl_link;
@@ -2774,6 +2778,8 @@ static int __init dp_init(void)
27742778
ovs_flow_exit();
27752779
error_unreg_rtnl_link:
27762780
ovs_internal_dev_rtnl_link_unregister();
2781+
error_action_fifos_exit:
2782+
action_fifos_exit();
27772783
error:
27782784
return err;
27792785
}
@@ -2789,6 +2795,7 @@ static void dp_cleanup(void)
27892795
ovs_vport_exit();
27902796
ovs_flow_exit();
27912797
ovs_internal_dev_rtnl_link_unregister();
2798+
action_fifos_exit();
27922799
}
27932800

27942801
module_init(dp_init);

net/openvswitch/datapath.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,9 @@ int ovs_execute_actions(struct datapath *dp, struct sk_buff *skb,
281281

282282
void ovs_dp_notify_wq(struct work_struct *work);
283283

284+
int action_fifos_init(void);
285+
void action_fifos_exit(void);
286+
284287
/* 'KEY' must not have any bits set outside of the 'MASK' */
285288
#define OVS_MASKED(OLD, KEY, MASK) ((KEY) | ((OLD) & ~(MASK)))
286289
#define OVS_SET_MASKED(OLD, KEY, MASK) ((OLD) = OVS_MASKED(OLD, KEY, MASK))

0 commit comments

Comments
 (0)