Commit 453a343c authored by David S. Miller's avatar David S. Miller

Merge branch 'ovs-upcall-issues'

Mark Gray says:

====================
openvswitch: per-cpu upcall patchwork issues

Some issues were raised by patchwork at:
https://patchwork.kernel.org/project/netdevbpf/patch/20210630095350.817785-1-mark.d.gray@redhat.com/#24285159
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents f9b282b3 076999e4
...@@ -70,7 +70,7 @@ enum ovs_datapath_cmd { ...@@ -70,7 +70,7 @@ enum ovs_datapath_cmd {
* set on the datapath port (for OVS_ACTION_ATTR_MISS). Only valid on * set on the datapath port (for OVS_ACTION_ATTR_MISS). Only valid on
* %OVS_DP_CMD_NEW requests. A value of zero indicates that upcalls should * %OVS_DP_CMD_NEW requests. A value of zero indicates that upcalls should
* not be sent. * not be sent.
* OVS_DP_ATTR_PER_CPU_PIDS: Per-cpu array of PIDs for upcalls when * @OVS_DP_ATTR_PER_CPU_PIDS: Per-cpu array of PIDs for upcalls when
* OVS_DP_F_DISPATCH_UPCALL_PER_CPU feature is set. * OVS_DP_F_DISPATCH_UPCALL_PER_CPU feature is set.
* @OVS_DP_ATTR_STATS: Statistics about packets that have passed through the * @OVS_DP_ATTR_STATS: Statistics about packets that have passed through the
* datapath. Always present in notifications. * datapath. Always present in notifications.
...@@ -89,8 +89,8 @@ enum ovs_datapath_attr { ...@@ -89,8 +89,8 @@ enum ovs_datapath_attr {
OVS_DP_ATTR_USER_FEATURES, /* OVS_DP_F_* */ OVS_DP_ATTR_USER_FEATURES, /* OVS_DP_F_* */
OVS_DP_ATTR_PAD, OVS_DP_ATTR_PAD,
OVS_DP_ATTR_MASKS_CACHE_SIZE, OVS_DP_ATTR_MASKS_CACHE_SIZE,
OVS_DP_ATTR_PER_CPU_PIDS, /* Netlink PIDS to receive upcalls in per-cpu OVS_DP_ATTR_PER_CPU_PIDS, /* Netlink PIDS to receive upcalls in
* dispatch mode * per-cpu dispatch mode
*/ */
__OVS_DP_ATTR_MAX __OVS_DP_ATTR_MAX
}; };
......
...@@ -924,9 +924,11 @@ static int output_userspace(struct datapath *dp, struct sk_buff *skb, ...@@ -924,9 +924,11 @@ static int output_userspace(struct datapath *dp, struct sk_buff *skb,
break; break;
case OVS_USERSPACE_ATTR_PID: case OVS_USERSPACE_ATTR_PID:
if (dp->user_features & OVS_DP_F_DISPATCH_UPCALL_PER_CPU) if (dp->user_features &
OVS_DP_F_DISPATCH_UPCALL_PER_CPU)
upcall.portid = upcall.portid =
ovs_dp_get_upcall_portid(dp, smp_processor_id()); ovs_dp_get_upcall_portid(dp,
smp_processor_id());
else else
upcall.portid = nla_get_u32(a); upcall.portid = nla_get_u32(a);
break; break;
......
...@@ -168,7 +168,7 @@ static void destroy_dp_rcu(struct rcu_head *rcu) ...@@ -168,7 +168,7 @@ static void destroy_dp_rcu(struct rcu_head *rcu)
free_percpu(dp->stats_percpu); free_percpu(dp->stats_percpu);
kfree(dp->ports); kfree(dp->ports);
ovs_meters_exit(dp); ovs_meters_exit(dp);
kfree(dp->upcall_portids); kfree(rcu_dereference_raw(dp->upcall_portids));
kfree(dp); kfree(dp);
} }
...@@ -244,7 +244,8 @@ void ovs_dp_process_packet(struct sk_buff *skb, struct sw_flow_key *key) ...@@ -244,7 +244,8 @@ void ovs_dp_process_packet(struct sk_buff *skb, struct sw_flow_key *key)
upcall.cmd = OVS_PACKET_CMD_MISS; upcall.cmd = OVS_PACKET_CMD_MISS;
if (dp->user_features & OVS_DP_F_DISPATCH_UPCALL_PER_CPU) if (dp->user_features & OVS_DP_F_DISPATCH_UPCALL_PER_CPU)
upcall.portid = ovs_dp_get_upcall_portid(dp, smp_processor_id()); upcall.portid =
ovs_dp_get_upcall_portid(dp, smp_processor_id());
else else
upcall.portid = ovs_vport_find_upcall_portid(p, skb); upcall.portid = ovs_vport_find_upcall_portid(p, skb);
...@@ -1636,13 +1637,16 @@ u32 ovs_dp_get_upcall_portid(const struct datapath *dp, uint32_t cpu_id) ...@@ -1636,13 +1637,16 @@ u32 ovs_dp_get_upcall_portid(const struct datapath *dp, uint32_t cpu_id)
if (dp_nlsk_pids) { if (dp_nlsk_pids) {
if (cpu_id < dp_nlsk_pids->n_pids) { if (cpu_id < dp_nlsk_pids->n_pids) {
return dp_nlsk_pids->pids[cpu_id]; return dp_nlsk_pids->pids[cpu_id];
} else if (dp_nlsk_pids->n_pids > 0 && cpu_id >= dp_nlsk_pids->n_pids) { } else if (dp_nlsk_pids->n_pids > 0 &&
/* If the number of netlink PIDs is mismatched with the number of cpu_id >= dp_nlsk_pids->n_pids) {
* CPUs as seen by the kernel, log this and send the upcall to an /* If the number of netlink PIDs is mismatched with
* arbitrary socket (0) in order to not drop packets * the number of CPUs as seen by the kernel, log this
* and send the upcall to an arbitrary socket (0) in
* order to not drop packets
*/ */
pr_info_ratelimited("cpu_id mismatch with handler threads"); pr_info_ratelimited("cpu_id mismatch with handler threads");
return dp_nlsk_pids->pids[cpu_id % dp_nlsk_pids->n_pids]; return dp_nlsk_pids->pids[cpu_id %
dp_nlsk_pids->n_pids];
} else { } else {
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment