netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [patch net-next 0/3] team: couple patches
@ 2012-04-20 14:42 Jiri Pirko
  2012-04-20 14:42 ` [patch net-next 1/3] team: lb: let userspace care about port macs Jiri Pirko
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Jiri Pirko @ 2012-04-20 14:42 UTC (permalink / raw)
  To: netdev; +Cc: davem, eric.dumazet

Jiri Pirko (3):
  team: lb: let userspace care about port macs
  team: allow to enable/disable ports
  team: add per-port option for enabling/disabling ports

 drivers/net/team/team.c                  |   75 +++++++++++++++++++++++------
 drivers/net/team/team_mode_loadbalance.c |   14 +-----
 drivers/net/team/team_mode_roundrobin.c  |    2 +-
 include/linux/if_team.h                  |   15 +++---
 4 files changed, 69 insertions(+), 37 deletions(-)

-- 
1.7.9.1

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [patch net-next 1/3] team: lb: let userspace care about port macs
  2012-04-20 14:42 [patch net-next 0/3] team: couple patches Jiri Pirko
@ 2012-04-20 14:42 ` Jiri Pirko
  2012-04-20 14:42 ` [patch net-next 2/3] team: allow to enable/disable ports Jiri Pirko
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Jiri Pirko @ 2012-04-20 14:42 UTC (permalink / raw)
  To: netdev; +Cc: davem, eric.dumazet

Better to leave this for userspace

Signed-off-by: Jiri Pirko <jpirko@redhat.com>
---
 drivers/net/team/team_mode_loadbalance.c |   12 ------------
 1 files changed, 0 insertions(+), 12 deletions(-)

diff --git a/drivers/net/team/team_mode_loadbalance.c b/drivers/net/team/team_mode_loadbalance.c
index 2b506b2..438d5b8 100644
--- a/drivers/net/team/team_mode_loadbalance.c
+++ b/drivers/net/team/team_mode_loadbalance.c
@@ -142,22 +142,10 @@ static void lb_exit(struct team *team)
 				ARRAY_SIZE(lb_options));
 }
 
-static int lb_port_enter(struct team *team, struct team_port *port)
-{
-	return team_port_set_team_mac(port);
-}
-
-static void lb_port_change_mac(struct team *team, struct team_port *port)
-{
-	team_port_set_team_mac(port);
-}
-
 static const struct team_mode_ops lb_mode_ops = {
 	.init			= lb_init,
 	.exit			= lb_exit,
 	.transmit		= lb_transmit,
-	.port_enter		= lb_port_enter,
-	.port_change_mac	= lb_port_change_mac,
 };
 
 static struct team_mode lb_mode = {
-- 
1.7.9.1

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [patch net-next 2/3] team: allow to enable/disable ports
  2012-04-20 14:42 [patch net-next 0/3] team: couple patches Jiri Pirko
  2012-04-20 14:42 ` [patch net-next 1/3] team: lb: let userspace care about port macs Jiri Pirko
@ 2012-04-20 14:42 ` Jiri Pirko
  2012-04-20 14:42 ` [patch net-next 3/3] team: add per-port option for enabling/disabling ports Jiri Pirko
  2012-04-21 20:27 ` [patch net-next 0/3] team: couple patches David Miller
  3 siblings, 0 replies; 5+ messages in thread
From: Jiri Pirko @ 2012-04-20 14:42 UTC (permalink / raw)
  To: netdev; +Cc: davem, eric.dumazet

This patch changes content of hashlist (used to get port struct by
computed index (0...en_port_count-1)). Now the hash list contains only
enabled ports so userspace will be able to say what ports can be used
for tx/rx. This becomes handy when userspace will need to disable ports
which does not belong to active aggregator. By default, newly added port
is enabled.

Signed-off-by: Jiri Pirko <jpirko@redhat.com>
---
 drivers/net/team/team.c                  |   51 ++++++++++++++++++++---------
 drivers/net/team/team_mode_loadbalance.c |    2 +-
 drivers/net/team/team_mode_roundrobin.c  |    2 +-
 include/linux/if_team.h                  |   15 +++++----
 4 files changed, 45 insertions(+), 25 deletions(-)

diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
index 153a62d..fe7ca40 100644
--- a/drivers/net/team/team.c
+++ b/drivers/net/team/team.c
@@ -559,6 +559,8 @@ static int team_change_mode(struct team *team, const char *kind)
  * Rx path frame handler
  ************************/
 
+static bool team_port_enabled(struct team_port *port);
+
 /* note: already called with rcu_read_lock */
 static rx_handler_result_t team_handle_frame(struct sk_buff **pskb)
 {
@@ -575,8 +577,12 @@ static rx_handler_result_t team_handle_frame(struct sk_buff **pskb)
 
 	port = team_port_get_rcu(skb->dev);
 	team = port->team;
-
-	res = team->ops.receive(team, port, skb);
+	if (!team_port_enabled(port)) {
+		/* allow exact match delivery for disabled ports */
+		res = RX_HANDLER_EXACT;
+	} else {
+		res = team->ops.receive(team, port, skb);
+	}
 	if (res == RX_HANDLER_ANOTHER) {
 		struct team_pcpu_stats *pcpu_stats;
 
@@ -612,17 +618,25 @@ static bool team_port_find(const struct team *team,
 	return false;
 }
 
+static bool team_port_enabled(struct team_port *port)
+{
+	return port->index != -1;
+}
+
 /*
- * Add/delete port to the team port list. Write guarded by rtnl_lock.
- * Takes care of correct port->index setup (might be racy).
+ * Enable/disable port by adding to enabled port hashlist and setting
+ * port->index (Might be racy so reader could see incorrect ifindex when
+ * processing a flying packet, but that is not a problem). Write guarded
+ * by team->lock.
  */
-static void team_port_list_add_port(struct team *team,
-				    struct team_port *port)
+static void team_port_enable(struct team *team,
+			     struct team_port *port)
 {
-	port->index = team->port_count++;
+	if (team_port_enabled(port))
+		return;
+	port->index = team->en_port_count++;
 	hlist_add_head_rcu(&port->hlist,
 			   team_port_index_hash(team, port->index));
-	list_add_tail_rcu(&port->list, &team->port_list);
 }
 
 static void __reconstruct_port_hlist(struct team *team, int rm_index)
@@ -630,7 +644,7 @@ static void __reconstruct_port_hlist(struct team *team, int rm_index)
 	int i;
 	struct team_port *port;
 
-	for (i = rm_index + 1; i < team->port_count; i++) {
+	for (i = rm_index + 1; i < team->en_port_count; i++) {
 		port = team_get_port_by_index(team, i);
 		hlist_del_rcu(&port->hlist);
 		port->index--;
@@ -639,15 +653,17 @@ static void __reconstruct_port_hlist(struct team *team, int rm_index)
 	}
 }
 
-static void team_port_list_del_port(struct team *team,
-				   struct team_port *port)
+static void team_port_disable(struct team *team,
+			      struct team_port *port)
 {
 	int rm_index = port->index;
 
+	if (!team_port_enabled(port))
+		return;
 	hlist_del_rcu(&port->hlist);
-	list_del_rcu(&port->list);
 	__reconstruct_port_hlist(team, rm_index);
-	team->port_count--;
+	team->en_port_count--;
+	port->index = -1;
 }
 
 #define TEAM_VLAN_FEATURES (NETIF_F_ALL_CSUM | NETIF_F_SG | \
@@ -800,7 +816,9 @@ static int team_port_add(struct team *team, struct net_device *port_dev)
 		goto err_option_port_add;
 	}
 
-	team_port_list_add_port(team, port);
+	port->index = -1;
+	team_port_enable(team, port);
+	list_add_tail_rcu(&port->list, &team->port_list);
 	team_adjust_ops(team);
 	__team_compute_features(team);
 	__team_port_change_check(port, !!netif_carrier_ok(port_dev));
@@ -849,7 +867,8 @@ static int team_port_del(struct team *team, struct net_device *port_dev)
 
 	port->removed = true;
 	__team_port_change_check(port, false);
-	team_port_list_del_port(team, port);
+	team_port_disable(team, port);
+	list_del_rcu(&port->list);
 	team_adjust_ops(team);
 	team_option_port_del(team, port);
 	netdev_rx_handler_unregister(port_dev);
@@ -956,7 +975,7 @@ static int team_init(struct net_device *dev)
 		return -ENOMEM;
 
 	for (i = 0; i < TEAM_PORT_HASHENTRIES; i++)
-		INIT_HLIST_HEAD(&team->port_hlist[i]);
+		INIT_HLIST_HEAD(&team->en_port_hlist[i]);
 	INIT_LIST_HEAD(&team->port_list);
 
 	team_adjust_ops(team);
diff --git a/drivers/net/team/team_mode_loadbalance.c b/drivers/net/team/team_mode_loadbalance.c
index 438d5b8..86e8183 100644
--- a/drivers/net/team/team_mode_loadbalance.c
+++ b/drivers/net/team/team_mode_loadbalance.c
@@ -38,7 +38,7 @@ static bool lb_transmit(struct team *team, struct sk_buff *skb)
 	if (unlikely(!fp))
 		goto drop;
 	hash = SK_RUN_FILTER(fp, skb);
-	port_index = hash % team->port_count;
+	port_index = hash % team->en_port_count;
 	port = team_get_port_by_index_rcu(team, port_index);
 	if (unlikely(!port))
 		goto drop;
diff --git a/drivers/net/team/team_mode_roundrobin.c b/drivers/net/team/team_mode_roundrobin.c
index a0e8f80..6abfbdc 100644
--- a/drivers/net/team/team_mode_roundrobin.c
+++ b/drivers/net/team/team_mode_roundrobin.c
@@ -50,7 +50,7 @@ static bool rr_transmit(struct team *team, struct sk_buff *skb)
 	struct team_port *port;
 	int port_index;
 
-	port_index = rr_priv(team)->sent_packets++ % team->port_count;
+	port_index = rr_priv(team)->sent_packets++ % team->en_port_count;
 	port = team_get_port_by_index_rcu(team, port_index);
 	port = __get_first_port_up(team, port);
 	if (unlikely(!port))
diff --git a/include/linux/if_team.h b/include/linux/if_team.h
index 5fd5ab1..8185f57 100644
--- a/include/linux/if_team.h
+++ b/include/linux/if_team.h
@@ -28,10 +28,10 @@ struct team;
 
 struct team_port {
 	struct net_device *dev;
-	struct hlist_node hlist; /* node in hash list */
+	struct hlist_node hlist; /* node in enabled ports hash list */
 	struct list_head list; /* node in ordinary list */
 	struct team *team;
-	int index;
+	int index; /* index of enabled port. If disabled, it's set to -1 */
 
 	bool linkup; /* either state.linkup or user.linkup */
 
@@ -125,11 +125,12 @@ struct team {
 	struct mutex lock; /* used for overall locking, e.g. port lists write */
 
 	/*
-	 * port lists with port count
+	 * List of enabled ports and their count
 	 */
-	int port_count;
-	struct hlist_head port_hlist[TEAM_PORT_HASHENTRIES];
-	struct list_head port_list;
+	int en_port_count;
+	struct hlist_head en_port_hlist[TEAM_PORT_HASHENTRIES];
+
+	struct list_head port_list; /* list of all ports */
 
 	struct list_head option_list;
 	struct list_head option_inst_list; /* list of option instances */
@@ -142,7 +143,7 @@ struct team {
 static inline struct hlist_head *team_port_index_hash(struct team *team,
 						      int port_index)
 {
-	return &team->port_hlist[port_index & (TEAM_PORT_HASHENTRIES - 1)];
+	return &team->en_port_hlist[port_index & (TEAM_PORT_HASHENTRIES - 1)];
 }
 
 static inline struct team_port *team_get_port_by_index(struct team *team,
-- 
1.7.9.1

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [patch net-next 3/3] team: add per-port option for enabling/disabling ports
  2012-04-20 14:42 [patch net-next 0/3] team: couple patches Jiri Pirko
  2012-04-20 14:42 ` [patch net-next 1/3] team: lb: let userspace care about port macs Jiri Pirko
  2012-04-20 14:42 ` [patch net-next 2/3] team: allow to enable/disable ports Jiri Pirko
@ 2012-04-20 14:42 ` Jiri Pirko
  2012-04-21 20:27 ` [patch net-next 0/3] team: couple patches David Miller
  3 siblings, 0 replies; 5+ messages in thread
From: Jiri Pirko @ 2012-04-20 14:42 UTC (permalink / raw)
  To: netdev; +Cc: davem, eric.dumazet

Signed-off-by: Jiri Pirko <jpirko@redhat.com>
---
 drivers/net/team/team.c |   24 ++++++++++++++++++++++++
 1 files changed, 24 insertions(+), 0 deletions(-)

diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
index fe7ca40..c61ae35 100644
--- a/drivers/net/team/team.c
+++ b/drivers/net/team/team.c
@@ -904,6 +904,23 @@ static int team_mode_option_set(struct team *team, struct team_gsetter_ctx *ctx)
 	return team_change_mode(team, ctx->data.str_val);
 }
 
+static int team_port_en_option_get(struct team *team,
+				   struct team_gsetter_ctx *ctx)
+{
+	ctx->data.bool_val = team_port_enabled(ctx->port);
+	return 0;
+}
+
+static int team_port_en_option_set(struct team *team,
+				   struct team_gsetter_ctx *ctx)
+{
+	if (ctx->data.bool_val)
+		team_port_enable(team, ctx->port);
+	else
+		team_port_disable(team, ctx->port);
+	return 0;
+}
+
 static int team_user_linkup_option_get(struct team *team,
 				       struct team_gsetter_ctx *ctx)
 {
@@ -946,6 +963,13 @@ static const struct team_option team_options[] = {
 		.setter = team_mode_option_set,
 	},
 	{
+		.name = "enabled",
+		.type = TEAM_OPTION_TYPE_BOOL,
+		.per_port = true,
+		.getter = team_port_en_option_get,
+		.setter = team_port_en_option_set,
+	},
+	{
 		.name = "user_linkup",
 		.type = TEAM_OPTION_TYPE_BOOL,
 		.per_port = true,
-- 
1.7.9.1

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [patch net-next 0/3] team: couple patches
  2012-04-20 14:42 [patch net-next 0/3] team: couple patches Jiri Pirko
                   ` (2 preceding siblings ...)
  2012-04-20 14:42 ` [patch net-next 3/3] team: add per-port option for enabling/disabling ports Jiri Pirko
@ 2012-04-21 20:27 ` David Miller
  3 siblings, 0 replies; 5+ messages in thread
From: David Miller @ 2012-04-21 20:27 UTC (permalink / raw)
  To: jpirko; +Cc: netdev, eric.dumazet

From: Jiri Pirko <jpirko@redhat.com>
Date: Fri, 20 Apr 2012 16:42:03 +0200

> Jiri Pirko (3):
>   team: lb: let userspace care about port macs
>   team: allow to enable/disable ports
>   team: add per-port option for enabling/disabling ports

All applied, thanks Jiri.

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2012-04-21 20:27 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-04-20 14:42 [patch net-next 0/3] team: couple patches Jiri Pirko
2012-04-20 14:42 ` [patch net-next 1/3] team: lb: let userspace care about port macs Jiri Pirko
2012-04-20 14:42 ` [patch net-next 2/3] team: allow to enable/disable ports Jiri Pirko
2012-04-20 14:42 ` [patch net-next 3/3] team: add per-port option for enabling/disabling ports Jiri Pirko
2012-04-21 20:27 ` [patch net-next 0/3] team: couple patches David Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).