diff mbox

[net-next] openvswitch: Provide OVS_DP_ATTR_UPCALL_PID in datapath messages

Message ID e7d0e105e879fb78ff3e5628147e41d52fb0cddd.1364941614.git.tgraf@suug.ch
State Awaiting Upstream, archived
Delegated to: David Miller
Headers show

Commit Message

Thomas Graf April 2, 2013, 10:28 p.m. UTC
The upcall port configured when adding a new datapath is currently
only provided to user space as part of the vport message. Therefore
user space has to request two separate messages which is prone to
race conditions.

Provide the upcall port of the local port (0) of a data path in the
datapath message to gain symmetry between the SET and GET command.

Signed-off-by: Thomas Graf <tgraf@suug.ch>
---
 net/openvswitch/datapath.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

Comments

Jesse Gross April 2, 2013, 11:30 p.m. UTC | #1
On Tue, Apr 2, 2013 at 3:28 PM, Thomas Graf <tgraf@suug.ch> wrote:
> The upcall port configured when adding a new datapath is currently
> only provided to user space as part of the vport message. Therefore
> user space has to request two separate messages which is prone to
> race conditions.
>
> Provide the upcall port of the local port (0) of a data path in the
> datapath message to gain symmetry between the SET and GET command.
>
> Signed-off-by: Thomas Graf <tgraf@suug.ch>

Can you describe the race condition some more?  The kernel doesn't
change the port ID on its own so even needing to request the value
seems rare.

Assigning the local ports upcall PID through datapath creation is
really somewhat of a hack since it's port state.  I don't disagree
that it's somewhat asymmetric now but it seems better to move away
from the current model if possible.
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Thomas Graf April 3, 2013, 7:33 a.m. UTC | #2
On 04/02/13 at 04:30pm, Jesse Gross wrote:
> Can you describe the race condition some more?  The kernel doesn't
> change the port ID on its own so even needing to request the value
> seems rare.

The upcall nlport is changeable with OVS_VPORT_CMD_SET and may
be received between the OVS_DP_CMD_GET and OVS_VPORT_CMD_GET.

> Assigning the local ports upcall PID through datapath creation is
> really somewhat of a hack since it's port state.  I don't disagree
> that it's somewhat asymmetric now but it seems better to move away
> from the current model if possible.

Would you suggest to wait with local vport creation if no upcall
nlport is provided and let new user space binaries create the local
port explicitly?

We can't get rid of the attribute in datapath messages w/o breaking
ABI but we could make its use optional I guess.
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Jesse Gross April 3, 2013, 8:17 p.m. UTC | #3
On Wed, Apr 3, 2013 at 12:33 AM, Thomas Graf <tgraf@suug.ch> wrote:
> On 04/02/13 at 04:30pm, Jesse Gross wrote:
>> Can you describe the race condition some more?  The kernel doesn't
>> change the port ID on its own so even needing to request the value
>> seems rare.
>
> The upcall nlport is changeable with OVS_VPORT_CMD_SET and may
> be received between the OVS_DP_CMD_GET and OVS_VPORT_CMD_GET.
>
>> Assigning the local ports upcall PID through datapath creation is
>> really somewhat of a hack since it's port state.  I don't disagree
>> that it's somewhat asymmetric now but it seems better to move away
>> from the current model if possible.
>
> Would you suggest to wait with local vport creation if no upcall
> nlport is provided and let new user space binaries create the local
> port explicitly?
>
> We can't get rid of the attribute in datapath messages w/o breaking
> ABI but we could make its use optional I guess.

We have to keep the local port as part of datapath creation since it
is used as an identifier for the datapath itself.  However, you could
probably achieve the same result by using a port ID of zero for the
local port, which will prevent it from doing upcalls.  You could then
set it to a real value when you want to "create" it (this is actually
what OVS userspace does).  I think this is probably about as close to
removing it as we can get.
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
index d406503..e9b9469 100644
--- a/net/openvswitch/datapath.c
+++ b/net/openvswitch/datapath.c
@@ -1240,6 +1240,7 @@  static size_t ovs_dp_cmd_msg_size(void)
 	size_t msgsize = NLMSG_ALIGN(sizeof(struct ovs_header));
 
 	msgsize += nla_total_size(IFNAMSIZ);
+	msgsize += nla_total_size(4); /* OVS_DP_ATTR_UPCALL_PID */
 	msgsize += nla_total_size(sizeof(struct ovs_dp_stats));
 
 	return msgsize;
@@ -1250,6 +1251,7 @@  static int ovs_dp_cmd_fill_info(struct datapath *dp, struct sk_buff *skb,
 {
 	struct ovs_header *ovs_header;
 	struct ovs_dp_stats dp_stats;
+	struct vport *local;
 	int err;
 
 	ovs_header = genlmsg_put(skb, portid, seq, &dp_datapath_genl_family,
@@ -1261,17 +1263,24 @@  static int ovs_dp_cmd_fill_info(struct datapath *dp, struct sk_buff *skb,
 
 	rcu_read_lock();
 	err = nla_put_string(skb, OVS_DP_ATTR_NAME, ovs_dp_name(dp));
-	rcu_read_unlock();
 	if (err)
 		goto nla_put_failure;
 
+	local = ovs_vport_rcu(dp, OVSP_LOCAL);
+	if (local &&
+	    nla_put_u32(skb, OVS_DP_ATTR_UPCALL_PID, local->upcall_portid))
+		goto nla_put_failure;
+
 	get_dp_stats(dp, &dp_stats);
 	if (nla_put(skb, OVS_DP_ATTR_STATS, sizeof(struct ovs_dp_stats), &dp_stats))
 		goto nla_put_failure;
 
+	rcu_read_unlock();
+
 	return genlmsg_end(skb, ovs_header);
 
 nla_put_failure:
+	rcu_read_unlock();
 	genlmsg_cancel(skb, ovs_header);
 error:
 	return -EMSGSIZE;