aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/team
diff options
context:
space:
mode:
authorJiri Pirko <jiri@resnulli.us>2013-03-05 20:31:13 -0500
committerDavid S. Miller <davem@davemloft.net>2013-03-06 14:55:20 -0500
commit753f993911b32e479b4fab5d228dc07c11d1e7e7 (patch)
treef2b3e9f3d6c06366ac24e5222f2475b319bc379f /drivers/net/team
parentacbba0d0f88e2577b9d92b61b136d13f65831a52 (diff)
team: introduce random mode
As suggested by Eric Dumazet, allow user to select mode which chooses TX port randomly. Functionality should be more of less similar to round-robin mode with even lower overhead. Signed-off-by: Jiri Pirko <jiri@resnulli.us> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/team')
-rw-r--r--drivers/net/team/Kconfig12
-rw-r--r--drivers/net/team/Makefile1
-rw-r--r--drivers/net/team/team_mode_random.c71
-rw-r--r--drivers/net/team/team_mode_roundrobin.c22
4 files changed, 85 insertions, 21 deletions
diff --git a/drivers/net/team/Kconfig b/drivers/net/team/Kconfig
index c3011af68e91..c853d84fd99f 100644
--- a/drivers/net/team/Kconfig
+++ b/drivers/net/team/Kconfig
@@ -37,6 +37,18 @@ config NET_TEAM_MODE_ROUNDROBIN
37 To compile this team mode as a module, choose M here: the module 37 To compile this team mode as a module, choose M here: the module
38 will be called team_mode_roundrobin. 38 will be called team_mode_roundrobin.
39 39
40config NET_TEAM_MODE_RANDOM
41 tristate "Random mode support"
42 depends on NET_TEAM
43 ---help---
44 Basic mode where port used for transmitting packets is selected
45 randomly.
46
47 All added ports are setup to have team's device address.
48
49 To compile this team mode as a module, choose M here: the module
50 will be called team_mode_random.
51
40config NET_TEAM_MODE_ACTIVEBACKUP 52config NET_TEAM_MODE_ACTIVEBACKUP
41 tristate "Active-backup mode support" 53 tristate "Active-backup mode support"
42 depends on NET_TEAM 54 depends on NET_TEAM
diff --git a/drivers/net/team/Makefile b/drivers/net/team/Makefile
index 975763014e5a..c57e85889751 100644
--- a/drivers/net/team/Makefile
+++ b/drivers/net/team/Makefile
@@ -5,5 +5,6 @@
5obj-$(CONFIG_NET_TEAM) += team.o 5obj-$(CONFIG_NET_TEAM) += team.o
6obj-$(CONFIG_NET_TEAM_MODE_BROADCAST) += team_mode_broadcast.o 6obj-$(CONFIG_NET_TEAM_MODE_BROADCAST) += team_mode_broadcast.o
7obj-$(CONFIG_NET_TEAM_MODE_ROUNDROBIN) += team_mode_roundrobin.o 7obj-$(CONFIG_NET_TEAM_MODE_ROUNDROBIN) += team_mode_roundrobin.o
8obj-$(CONFIG_NET_TEAM_MODE_RANDOM) += team_mode_random.o
8obj-$(CONFIG_NET_TEAM_MODE_ACTIVEBACKUP) += team_mode_activebackup.o 9obj-$(CONFIG_NET_TEAM_MODE_ACTIVEBACKUP) += team_mode_activebackup.o
9obj-$(CONFIG_NET_TEAM_MODE_LOADBALANCE) += team_mode_loadbalance.o 10obj-$(CONFIG_NET_TEAM_MODE_LOADBALANCE) += team_mode_loadbalance.o
diff --git a/drivers/net/team/team_mode_random.c b/drivers/net/team/team_mode_random.c
new file mode 100644
index 000000000000..9eabfaa22f3e
--- /dev/null
+++ b/drivers/net/team/team_mode_random.c
@@ -0,0 +1,71 @@
1/*
2 * drivers/net/team/team_mode_random.c - Random mode for team
3 * Copyright (c) 2013 Jiri Pirko <jiri@resnulli.us>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 */
10
11#include <linux/kernel.h>
12#include <linux/types.h>
13#include <linux/module.h>
14#include <linux/init.h>
15#include <linux/skbuff.h>
16#include <linux/reciprocal_div.h>
17#include <linux/if_team.h>
18
19static u32 random_N(unsigned int N)
20{
21 return reciprocal_divide(random32(), N);
22}
23
24static bool rnd_transmit(struct team *team, struct sk_buff *skb)
25{
26 struct team_port *port;
27 int port_index;
28
29 port_index = random_N(team->en_port_count);
30 port = team_get_port_by_index_rcu(team, port_index);
31 port = team_get_first_port_txable_rcu(team, port);
32 if (unlikely(!port))
33 goto drop;
34 if (team_dev_queue_xmit(team, port, skb))
35 return false;
36 return true;
37
38drop:
39 dev_kfree_skb_any(skb);
40 return false;
41}
42
43static const struct team_mode_ops rnd_mode_ops = {
44 .transmit = rnd_transmit,
45 .port_enter = team_modeop_port_enter,
46 .port_change_dev_addr = team_modeop_port_change_dev_addr,
47};
48
49static const struct team_mode rnd_mode = {
50 .kind = "random",
51 .owner = THIS_MODULE,
52 .ops = &rnd_mode_ops,
53};
54
55static int __init rnd_init_module(void)
56{
57 return team_mode_register(&rnd_mode);
58}
59
60static void __exit rnd_cleanup_module(void)
61{
62 team_mode_unregister(&rnd_mode);
63}
64
65module_init(rnd_init_module);
66module_exit(rnd_cleanup_module);
67
68MODULE_LICENSE("GPL v2");
69MODULE_AUTHOR("Jiri Pirko <jiri@resnulli.us>");
70MODULE_DESCRIPTION("Random mode for team");
71MODULE_ALIAS("team-mode-random");
diff --git a/drivers/net/team/team_mode_roundrobin.c b/drivers/net/team/team_mode_roundrobin.c
index ed63a6bc66ce..d268e4de781b 100644
--- a/drivers/net/team/team_mode_roundrobin.c
+++ b/drivers/net/team/team_mode_roundrobin.c
@@ -25,26 +25,6 @@ static struct rr_priv *rr_priv(struct team *team)
25 return (struct rr_priv *) &team->mode_priv; 25 return (struct rr_priv *) &team->mode_priv;
26} 26}
27 27
28static struct team_port *__get_first_port_up(struct team *team,
29 struct team_port *port)
30{
31 struct team_port *cur;
32
33 if (team_port_txable(port))
34 return port;
35 cur = port;
36 list_for_each_entry_continue_rcu(cur, &team->port_list, list)
37 if (team_port_txable(port))
38 return cur;
39 list_for_each_entry_rcu(cur, &team->port_list, list) {
40 if (cur == port)
41 break;
42 if (team_port_txable(port))
43 return cur;
44 }
45 return NULL;
46}
47
48static bool rr_transmit(struct team *team, struct sk_buff *skb) 28static bool rr_transmit(struct team *team, struct sk_buff *skb)
49{ 29{
50 struct team_port *port; 30 struct team_port *port;
@@ -52,7 +32,7 @@ static bool rr_transmit(struct team *team, struct sk_buff *skb)
52 32
53 port_index = rr_priv(team)->sent_packets++ % team->en_port_count; 33 port_index = rr_priv(team)->sent_packets++ % team->en_port_count;
54 port = team_get_port_by_index_rcu(team, port_index); 34 port = team_get_port_by_index_rcu(team, port_index);
55 port = __get_first_port_up(team, port); 35 port = team_get_first_port_txable_rcu(team, port);
56 if (unlikely(!port)) 36 if (unlikely(!port))
57 goto drop; 37 goto drop;
58 if (team_dev_queue_xmit(team, port, skb)) 38 if (team_dev_queue_xmit(team, port, skb))