Commit dec1e90e authored by nikolay@redhat.com's avatar nikolay@redhat.com Committed by David S. Miller

bonding: convert to list API and replace bond's custom list

This patch aims to remove struct bonding's first_slave and struct
slave's next and prev pointers, and replace them with the standard Linux
list API. The old macros are converted to list API as well and some new
primitives are available now. The checks if there're slaves that used
slave_cnt have been replaced by the list_empty macro.
Also a few small style fixes, changing longest -> shortest line in local
variable declarations, leaving an empty line before return and removing
unnecessary brackets.
This is the first step to gradual RCU conversion.
Signed-off-by: default avatarNikolay Aleksandrov <nikolay@redhat.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 439677d7
...@@ -143,10 +143,9 @@ static inline struct bonding *__get_bond_by_port(struct port *port) ...@@ -143,10 +143,9 @@ static inline struct bonding *__get_bond_by_port(struct port *port)
*/ */
static inline struct port *__get_first_port(struct bonding *bond) static inline struct port *__get_first_port(struct bonding *bond)
{ {
if (bond->slave_cnt == 0) struct slave *first_slave = bond_first_slave(bond);
return NULL;
return &(SLAVE_AD_INFO(bond->first_slave).port); return first_slave ? &(SLAVE_AD_INFO(first_slave).port) : NULL;
} }
/** /**
...@@ -159,13 +158,16 @@ static inline struct port *__get_first_port(struct bonding *bond) ...@@ -159,13 +158,16 @@ static inline struct port *__get_first_port(struct bonding *bond)
static inline struct port *__get_next_port(struct port *port) static inline struct port *__get_next_port(struct port *port)
{ {
struct bonding *bond = __get_bond_by_port(port); struct bonding *bond = __get_bond_by_port(port);
struct slave *slave = port->slave; struct slave *slave = port->slave, *slave_next;
// If there's no bond for this port, or this is the last slave // If there's no bond for this port, or this is the last slave
if ((bond == NULL) || (slave->next == bond->first_slave)) if (bond == NULL)
return NULL;
slave_next = bond_next_slave(bond, slave);
if (!slave_next || bond_is_first_slave(bond, slave_next))
return NULL; return NULL;
return &(SLAVE_AD_INFO(slave->next).port); return &(SLAVE_AD_INFO(slave_next).port);
} }
/** /**
...@@ -178,12 +180,14 @@ static inline struct port *__get_next_port(struct port *port) ...@@ -178,12 +180,14 @@ static inline struct port *__get_next_port(struct port *port)
static inline struct aggregator *__get_first_agg(struct port *port) static inline struct aggregator *__get_first_agg(struct port *port)
{ {
struct bonding *bond = __get_bond_by_port(port); struct bonding *bond = __get_bond_by_port(port);
struct slave *first_slave;
// If there's no bond for this port, or bond has no slaves // If there's no bond for this port, or bond has no slaves
if ((bond == NULL) || (bond->slave_cnt == 0)) if (bond == NULL)
return NULL; return NULL;
first_slave = bond_first_slave(bond);
return &(SLAVE_AD_INFO(bond->first_slave).aggregator); return first_slave ? &(SLAVE_AD_INFO(first_slave).aggregator) : NULL;
} }
/** /**
...@@ -195,14 +199,17 @@ static inline struct aggregator *__get_first_agg(struct port *port) ...@@ -195,14 +199,17 @@ static inline struct aggregator *__get_first_agg(struct port *port)
*/ */
static inline struct aggregator *__get_next_agg(struct aggregator *aggregator) static inline struct aggregator *__get_next_agg(struct aggregator *aggregator)
{ {
struct slave *slave = aggregator->slave; struct slave *slave = aggregator->slave, *slave_next;
struct bonding *bond = bond_get_bond_by_slave(slave); struct bonding *bond = bond_get_bond_by_slave(slave);
// If there's no bond for this aggregator, or this is the last slave // If there's no bond for this aggregator, or this is the last slave
if ((bond == NULL) || (slave->next == bond->first_slave)) if (bond == NULL)
return NULL;
slave_next = bond_next_slave(bond, slave);
if (!slave_next || bond_is_first_slave(bond, slave_next))
return NULL; return NULL;
return &(SLAVE_AD_INFO(slave->next).aggregator); return &(SLAVE_AD_INFO(slave_next).aggregator);
} }
/* /*
...@@ -2110,7 +2117,7 @@ void bond_3ad_state_machine_handler(struct work_struct *work) ...@@ -2110,7 +2117,7 @@ void bond_3ad_state_machine_handler(struct work_struct *work)
read_lock(&bond->lock); read_lock(&bond->lock);
//check if there are any slaves //check if there are any slaves
if (bond->slave_cnt == 0) if (list_empty(&bond->slave_list))
goto re_arm; goto re_arm;
// check if agg_select_timer timer after initialize is timed out // check if agg_select_timer timer after initialize is timed out
...@@ -2336,8 +2343,12 @@ void bond_3ad_handle_link_change(struct slave *slave, char link) ...@@ -2336,8 +2343,12 @@ void bond_3ad_handle_link_change(struct slave *slave, char link)
int bond_3ad_set_carrier(struct bonding *bond) int bond_3ad_set_carrier(struct bonding *bond)
{ {
struct aggregator *active; struct aggregator *active;
struct slave *first_slave;
active = __get_active_agg(&(SLAVE_AD_INFO(bond->first_slave).aggregator)); first_slave = bond_first_slave(bond);
if (!first_slave)
return 0;
active = __get_active_agg(&(SLAVE_AD_INFO(first_slave).aggregator));
if (active) { if (active) {
/* are enough slaves available to consider link up? */ /* are enough slaves available to consider link up? */
if (active->num_of_ports < bond->params.min_links) { if (active->num_of_ports < bond->params.min_links) {
...@@ -2432,7 +2443,7 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev) ...@@ -2432,7 +2443,7 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev)
slave_agg_no = bond->xmit_hash_policy(skb, slaves_in_agg); slave_agg_no = bond->xmit_hash_policy(skb, slaves_in_agg);
bond_for_each_slave(bond, slave, i) { bond_for_each_slave(bond, slave) {
struct aggregator *agg = SLAVE_AD_INFO(slave).port.aggregator; struct aggregator *agg = SLAVE_AD_INFO(slave).port.aggregator;
if (agg && (agg->aggregator_identifier == agg_id)) { if (agg && (agg->aggregator_identifier == agg_id)) {
...@@ -2501,7 +2512,6 @@ int bond_3ad_lacpdu_recv(const struct sk_buff *skb, struct bonding *bond, ...@@ -2501,7 +2512,6 @@ int bond_3ad_lacpdu_recv(const struct sk_buff *skb, struct bonding *bond,
*/ */
void bond_3ad_update_lacp_rate(struct bonding *bond) void bond_3ad_update_lacp_rate(struct bonding *bond)
{ {
int i;
struct slave *slave; struct slave *slave;
struct port *port = NULL; struct port *port = NULL;
int lacp_fast; int lacp_fast;
...@@ -2509,7 +2519,7 @@ void bond_3ad_update_lacp_rate(struct bonding *bond) ...@@ -2509,7 +2519,7 @@ void bond_3ad_update_lacp_rate(struct bonding *bond)
write_lock_bh(&bond->lock); write_lock_bh(&bond->lock);
lacp_fast = bond->params.lacp_fast; lacp_fast = bond->params.lacp_fast;
bond_for_each_slave(bond, slave, i) { bond_for_each_slave(bond, slave) {
port = &(SLAVE_AD_INFO(slave).port); port = &(SLAVE_AD_INFO(slave).port);
if (port->slave == NULL) if (port->slave == NULL)
continue; continue;
......
...@@ -224,13 +224,12 @@ static struct slave *tlb_get_least_loaded_slave(struct bonding *bond) ...@@ -224,13 +224,12 @@ static struct slave *tlb_get_least_loaded_slave(struct bonding *bond)
{ {
struct slave *slave, *least_loaded; struct slave *slave, *least_loaded;
long long max_gap; long long max_gap;
int i;
least_loaded = NULL; least_loaded = NULL;
max_gap = LLONG_MIN; max_gap = LLONG_MIN;
/* Find the slave with the largest gap */ /* Find the slave with the largest gap */
bond_for_each_slave(bond, slave, i) { bond_for_each_slave(bond, slave) {
if (SLAVE_IS_OK(slave)) { if (SLAVE_IS_OK(slave)) {
long long gap = compute_gap(slave); long long gap = compute_gap(slave);
...@@ -386,11 +385,10 @@ static struct slave *rlb_next_rx_slave(struct bonding *bond) ...@@ -386,11 +385,10 @@ static struct slave *rlb_next_rx_slave(struct bonding *bond)
struct slave *rx_slave, *slave, *start_at; struct slave *rx_slave, *slave, *start_at;
int i = 0; int i = 0;
if (bond_info->next_rx_slave) { if (bond_info->next_rx_slave)
start_at = bond_info->next_rx_slave; start_at = bond_info->next_rx_slave;
} else { else
start_at = bond->first_slave; start_at = bond_first_slave(bond);
}
rx_slave = NULL; rx_slave = NULL;
...@@ -405,7 +403,8 @@ static struct slave *rlb_next_rx_slave(struct bonding *bond) ...@@ -405,7 +403,8 @@ static struct slave *rlb_next_rx_slave(struct bonding *bond)
} }
if (rx_slave) { if (rx_slave) {
bond_info->next_rx_slave = rx_slave->next; slave = bond_next_slave(bond, rx_slave);
bond_info->next_rx_slave = slave;
} }
return rx_slave; return rx_slave;
...@@ -1173,9 +1172,8 @@ static int alb_handle_addr_collision_on_attach(struct bonding *bond, struct slav ...@@ -1173,9 +1172,8 @@ static int alb_handle_addr_collision_on_attach(struct bonding *bond, struct slav
{ {
struct slave *tmp_slave1, *free_mac_slave = NULL; struct slave *tmp_slave1, *free_mac_slave = NULL;
struct slave *has_bond_addr = bond->curr_active_slave; struct slave *has_bond_addr = bond->curr_active_slave;
int i;
if (bond->slave_cnt == 0) { if (list_empty(&bond->slave_list)) {
/* this is the first slave */ /* this is the first slave */
return 0; return 0;
} }
...@@ -1196,7 +1194,7 @@ static int alb_handle_addr_collision_on_attach(struct bonding *bond, struct slav ...@@ -1196,7 +1194,7 @@ static int alb_handle_addr_collision_on_attach(struct bonding *bond, struct slav
/* The slave's address is equal to the address of the bond. /* The slave's address is equal to the address of the bond.
* Search for a spare address in the bond for this slave. * Search for a spare address in the bond for this slave.
*/ */
bond_for_each_slave(bond, tmp_slave1, i) { bond_for_each_slave(bond, tmp_slave1) {
if (!bond_slave_has_mac(bond, tmp_slave1->perm_hwaddr)) { if (!bond_slave_has_mac(bond, tmp_slave1->perm_hwaddr)) {
/* no slave has tmp_slave1's perm addr /* no slave has tmp_slave1's perm addr
* as its curr addr * as its curr addr
...@@ -1246,17 +1244,15 @@ static int alb_handle_addr_collision_on_attach(struct bonding *bond, struct slav ...@@ -1246,17 +1244,15 @@ static int alb_handle_addr_collision_on_attach(struct bonding *bond, struct slav
*/ */
static int alb_set_mac_address(struct bonding *bond, void *addr) static int alb_set_mac_address(struct bonding *bond, void *addr)
{ {
struct sockaddr sa;
struct slave *slave, *stop_at;
char tmp_addr[ETH_ALEN]; char tmp_addr[ETH_ALEN];
struct slave *slave;
struct sockaddr sa;
int res; int res;
int i;
if (bond->alb_info.rlb_enabled) { if (bond->alb_info.rlb_enabled)
return 0; return 0;
}
bond_for_each_slave(bond, slave, i) { bond_for_each_slave(bond, slave) {
/* save net_device's current hw address */ /* save net_device's current hw address */
memcpy(tmp_addr, slave->dev->dev_addr, ETH_ALEN); memcpy(tmp_addr, slave->dev->dev_addr, ETH_ALEN);
...@@ -1276,8 +1272,7 @@ static int alb_set_mac_address(struct bonding *bond, void *addr) ...@@ -1276,8 +1272,7 @@ static int alb_set_mac_address(struct bonding *bond, void *addr)
sa.sa_family = bond->dev->type; sa.sa_family = bond->dev->type;
/* unwind from head to the slave that failed */ /* unwind from head to the slave that failed */
stop_at = slave; bond_for_each_slave_continue_reverse(bond, slave) {
bond_for_each_slave_from_to(bond, slave, i, bond->first_slave, stop_at) {
memcpy(tmp_addr, slave->dev->dev_addr, ETH_ALEN); memcpy(tmp_addr, slave->dev->dev_addr, ETH_ALEN);
dev_set_mac_address(slave->dev, &sa); dev_set_mac_address(slave->dev, &sa);
memcpy(slave->dev->dev_addr, tmp_addr, ETH_ALEN); memcpy(slave->dev->dev_addr, tmp_addr, ETH_ALEN);
...@@ -1460,11 +1455,10 @@ void bond_alb_monitor(struct work_struct *work) ...@@ -1460,11 +1455,10 @@ void bond_alb_monitor(struct work_struct *work)
alb_work.work); alb_work.work);
struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond)); struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
struct slave *slave; struct slave *slave;
int i;
read_lock(&bond->lock); read_lock(&bond->lock);
if (bond->slave_cnt == 0) { if (list_empty(&bond->slave_list)) {
bond_info->tx_rebalance_counter = 0; bond_info->tx_rebalance_counter = 0;
bond_info->lp_counter = 0; bond_info->lp_counter = 0;
goto re_arm; goto re_arm;
...@@ -1482,9 +1476,8 @@ void bond_alb_monitor(struct work_struct *work) ...@@ -1482,9 +1476,8 @@ void bond_alb_monitor(struct work_struct *work)
*/ */
read_lock(&bond->curr_slave_lock); read_lock(&bond->curr_slave_lock);
bond_for_each_slave(bond, slave, i) { bond_for_each_slave(bond, slave)
alb_send_learning_packets(slave, slave->dev->dev_addr); alb_send_learning_packets(slave, slave->dev->dev_addr);
}
read_unlock(&bond->curr_slave_lock); read_unlock(&bond->curr_slave_lock);
...@@ -1496,7 +1489,7 @@ void bond_alb_monitor(struct work_struct *work) ...@@ -1496,7 +1489,7 @@ void bond_alb_monitor(struct work_struct *work)
read_lock(&bond->curr_slave_lock); read_lock(&bond->curr_slave_lock);
bond_for_each_slave(bond, slave, i) { bond_for_each_slave(bond, slave) {
tlb_clear_slave(bond, slave, 1); tlb_clear_slave(bond, slave, 1);
if (slave == bond->curr_active_slave) { if (slave == bond->curr_active_slave) {
SLAVE_TLB_INFO(slave).load = SLAVE_TLB_INFO(slave).load =
...@@ -1602,9 +1595,8 @@ int bond_alb_init_slave(struct bonding *bond, struct slave *slave) ...@@ -1602,9 +1595,8 @@ int bond_alb_init_slave(struct bonding *bond, struct slave *slave)
*/ */
void bond_alb_deinit_slave(struct bonding *bond, struct slave *slave) void bond_alb_deinit_slave(struct bonding *bond, struct slave *slave)
{ {
if (bond->slave_cnt > 1) { if (!list_empty(&bond->slave_list))
alb_change_hw_addr_on_detach(bond, slave); alb_change_hw_addr_on_detach(bond, slave);
}
tlb_clear_slave(bond, slave, 0); tlb_clear_slave(bond, slave, 0);
...@@ -1661,9 +1653,8 @@ void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave ...@@ -1661,9 +1653,8 @@ void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave
{ {
struct slave *swap_slave; struct slave *swap_slave;
if (bond->curr_active_slave == new_slave) { if (bond->curr_active_slave == new_slave)
return; return;
}
if (bond->curr_active_slave && bond->alb_info.primary_is_promisc) { if (bond->curr_active_slave && bond->alb_info.primary_is_promisc) {
dev_set_promiscuity(bond->curr_active_slave->dev, -1); dev_set_promiscuity(bond->curr_active_slave->dev, -1);
...@@ -1674,9 +1665,8 @@ void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave ...@@ -1674,9 +1665,8 @@ void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave
swap_slave = bond->curr_active_slave; swap_slave = bond->curr_active_slave;
bond->curr_active_slave = new_slave; bond->curr_active_slave = new_slave;
if (!new_slave || (bond->slave_cnt == 0)) { if (!new_slave || list_empty(&bond->slave_list))
return; return;
}
/* set the new curr_active_slave to the bonds mac address /* set the new curr_active_slave to the bonds mac address
* i.e. swap mac addresses of old curr_active_slave and new curr_active_slave * i.e. swap mac addresses of old curr_active_slave and new curr_active_slave
...@@ -1689,9 +1679,8 @@ void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave ...@@ -1689,9 +1679,8 @@ void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave
* ignored so we can mess with their MAC addresses without * ignored so we can mess with their MAC addresses without
* fear of interference from transmit activity. * fear of interference from transmit activity.
*/ */
if (swap_slave) { if (swap_slave)
tlb_clear_slave(bond, swap_slave, 1); tlb_clear_slave(bond, swap_slave, 1);
}
tlb_clear_slave(bond, new_slave, 1); tlb_clear_slave(bond, new_slave, 1);
write_unlock_bh(&bond->curr_slave_lock); write_unlock_bh(&bond->curr_slave_lock);
......
This diff is collapsed.
...@@ -12,7 +12,6 @@ static void *bond_info_seq_start(struct seq_file *seq, loff_t *pos) ...@@ -12,7 +12,6 @@ static void *bond_info_seq_start(struct seq_file *seq, loff_t *pos)
struct bonding *bond = seq->private; struct bonding *bond = seq->private;
loff_t off = 0; loff_t off = 0;
struct slave *slave; struct slave *slave;
int i;
/* make sure the bond won't be taken away */ /* make sure the bond won't be taken away */
rcu_read_lock(); rcu_read_lock();
...@@ -21,10 +20,9 @@ static void *bond_info_seq_start(struct seq_file *seq, loff_t *pos) ...@@ -21,10 +20,9 @@ static void *bond_info_seq_start(struct seq_file *seq, loff_t *pos)
if (*pos == 0) if (*pos == 0)
return SEQ_START_TOKEN; return SEQ_START_TOKEN;
bond_for_each_slave(bond, slave, i) { bond_for_each_slave(bond, slave)
if (++off == *pos) if (++off == *pos)
return slave; return slave;
}
return NULL; return NULL;
} }
...@@ -36,11 +34,13 @@ static void *bond_info_seq_next(struct seq_file *seq, void *v, loff_t *pos) ...@@ -36,11 +34,13 @@ static void *bond_info_seq_next(struct seq_file *seq, void *v, loff_t *pos)
++*pos; ++*pos;
if (v == SEQ_START_TOKEN) if (v == SEQ_START_TOKEN)
return bond->first_slave; return bond_first_slave(bond);
slave = slave->next; if (bond_is_last_slave(bond, slave))
return NULL;
slave = bond_next_slave(bond, slave);
return (slave == bond->first_slave) ? NULL : slave; return slave;
} }
static void bond_info_seq_stop(struct seq_file *seq, void *v) static void bond_info_seq_stop(struct seq_file *seq, void *v)
......
...@@ -209,12 +209,12 @@ void bond_destroy_slave_symlinks(struct net_device *master, ...@@ -209,12 +209,12 @@ void bond_destroy_slave_symlinks(struct net_device *master,
static ssize_t bonding_show_slaves(struct device *d, static ssize_t bonding_show_slaves(struct device *d,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
struct slave *slave;
int i, res = 0;
struct bonding *bond = to_bond(d); struct bonding *bond = to_bond(d);
struct slave *slave;
int res = 0;
read_lock(&bond->lock); read_lock(&bond->lock);
bond_for_each_slave(bond, slave, i) { bond_for_each_slave(bond, slave) {
if (res > (PAGE_SIZE - IFNAMSIZ)) { if (res > (PAGE_SIZE - IFNAMSIZ)) {
/* not enough space for another interface name */ /* not enough space for another interface name */
if ((PAGE_SIZE - res) > 10) if ((PAGE_SIZE - res) > 10)
...@@ -227,6 +227,7 @@ static ssize_t bonding_show_slaves(struct device *d, ...@@ -227,6 +227,7 @@ static ssize_t bonding_show_slaves(struct device *d,
read_unlock(&bond->lock); read_unlock(&bond->lock);
if (res) if (res)
buf[res-1] = '\n'; /* eat the leftover space */ buf[res-1] = '\n'; /* eat the leftover space */
return res; return res;
} }
...@@ -325,7 +326,7 @@ static ssize_t bonding_store_mode(struct device *d, ...@@ -325,7 +326,7 @@ static ssize_t bonding_store_mode(struct device *d,
goto out; goto out;
} }
if (bond->slave_cnt > 0) { if (!list_empty(&bond->slave_list)) {
pr_err("unable to update mode of %s because it has slaves.\n", pr_err("unable to update mode of %s because it has slaves.\n",
bond->dev->name); bond->dev->name);
ret = -EPERM; ret = -EPERM;
...@@ -507,7 +508,7 @@ static ssize_t bonding_store_fail_over_mac(struct device *d, ...@@ -507,7 +508,7 @@ static ssize_t bonding_store_fail_over_mac(struct device *d,
if (!rtnl_trylock()) if (!rtnl_trylock())
return restart_syscall(); return restart_syscall();
if (bond->slave_cnt != 0) { if (!list_empty(&bond->slave_list)) {
pr_err("%s: Can't alter fail_over_mac with slaves in bond.\n", pr_err("%s: Can't alter fail_over_mac with slaves in bond.\n",
bond->dev->name); bond->dev->name);
ret = -EPERM; ret = -EPERM;
...@@ -668,7 +669,7 @@ static ssize_t bonding_store_arp_targets(struct device *d, ...@@ -668,7 +669,7 @@ static ssize_t bonding_store_arp_targets(struct device *d,
&newtarget); &newtarget);
/* not to race with bond_arp_rcv */ /* not to race with bond_arp_rcv */
write_lock_bh(&bond->lock); write_lock_bh(&bond->lock);
bond_for_each_slave(bond, slave, i) bond_for_each_slave(bond, slave)
slave->target_last_arp_rx[ind] = jiffies; slave->target_last_arp_rx[ind] = jiffies;
targets[ind] = newtarget; targets[ind] = newtarget;
write_unlock_bh(&bond->lock); write_unlock_bh(&bond->lock);
...@@ -694,7 +695,7 @@ static ssize_t bonding_store_arp_targets(struct device *d, ...@@ -694,7 +695,7 @@ static ssize_t bonding_store_arp_targets(struct device *d,
&newtarget); &newtarget);
write_lock_bh(&bond->lock); write_lock_bh(&bond->lock);
bond_for_each_slave(bond, slave, i) { bond_for_each_slave(bond, slave) {
targets_rx = slave->target_last_arp_rx; targets_rx = slave->target_last_arp_rx;
j = ind; j = ind;
for (; (j < BOND_MAX_ARP_TARGETS-1) && targets[j+1]; j++) for (; (j < BOND_MAX_ARP_TARGETS-1) && targets[j+1]; j++)
...@@ -1085,10 +1086,9 @@ static ssize_t bonding_store_primary(struct device *d, ...@@ -1085,10 +1086,9 @@ static ssize_t bonding_store_primary(struct device *d,
struct device_attribute *attr, struct device_attribute *attr,
const char *buf, size_t count) const char *buf, size_t count)
{ {
int i;
struct slave *slave;
struct bonding *bond = to_bond(d); struct bonding *bond = to_bond(d);
char ifname[IFNAMSIZ]; char ifname[IFNAMSIZ];
struct slave *slave;
if (!rtnl_trylock()) if (!rtnl_trylock())
return restart_syscall(); return restart_syscall();
...@@ -1114,7 +1114,7 @@ static ssize_t bonding_store_primary(struct device *d, ...@@ -1114,7 +1114,7 @@ static ssize_t bonding_store_primary(struct device *d,
goto out; goto out;
} }
bond_for_each_slave(bond, slave, i) { bond_for_each_slave(bond, slave) {
if (strncmp(slave->dev->name, ifname, IFNAMSIZ) == 0) { if (strncmp(slave->dev->name, ifname, IFNAMSIZ) == 0) {
pr_info("%s: Setting %s as primary slave.\n", pr_info("%s: Setting %s as primary slave.\n",
bond->dev->name, slave->dev->name); bond->dev->name, slave->dev->name);
...@@ -1260,16 +1260,14 @@ static ssize_t bonding_store_active_slave(struct device *d, ...@@ -1260,16 +1260,14 @@ static ssize_t bonding_store_active_slave(struct device *d,
struct device_attribute *attr, struct device_attribute *attr,
const char *buf, size_t count) const char *buf, size_t count)
{ {
int i; struct slave *slave, *old_active, *new_active;
struct slave *slave;
struct slave *old_active = NULL;
struct slave *new_active = NULL;
struct bonding *bond = to_bond(d); struct bonding *bond = to_bond(d);
char ifname[IFNAMSIZ]; char ifname[IFNAMSIZ];
if (!rtnl_trylock()) if (!rtnl_trylock())
return restart_syscall(); return restart_syscall();
old_active = new_active = NULL;
block_netpoll_tx(); block_netpoll_tx();
read_lock(&bond->lock); read_lock(&bond->lock);
write_lock_bh(&bond->curr_slave_lock); write_lock_bh(&bond->curr_slave_lock);
...@@ -1291,7 +1289,7 @@ static ssize_t bonding_store_active_slave(struct device *d, ...@@ -1291,7 +1289,7 @@ static ssize_t bonding_store_active_slave(struct device *d,
goto out; goto out;
} }
bond_for_each_slave(bond, slave, i) { bond_for_each_slave(bond, slave) {
if (strncmp(slave->dev->name, ifname, IFNAMSIZ) == 0) { if (strncmp(slave->dev->name, ifname, IFNAMSIZ) == 0) {
old_active = bond->curr_active_slave; old_active = bond->curr_active_slave;
new_active = slave; new_active = slave;
...@@ -1475,15 +1473,15 @@ static ssize_t bonding_show_queue_id(struct device *d, ...@@ -1475,15 +1473,15 @@ static ssize_t bonding_show_queue_id(struct device *d,
struct device_attribute *attr, struct device_attribute *attr,
char *buf) char *buf)
{ {
struct slave *slave;
int i, res = 0;
struct bonding *bond = to_bond(d); struct bonding *bond = to_bond(d);
struct slave *slave;
int res = 0;
if (!rtnl_trylock()) if (!rtnl_trylock())
return restart_syscall(); return restart_syscall();
read_lock(&bond->lock); read_lock(&bond->lock);
bond_for_each_slave(bond, slave, i) { bond_for_each_slave(bond, slave) {
if (res > (PAGE_SIZE - IFNAMSIZ - 6)) { if (res > (PAGE_SIZE - IFNAMSIZ - 6)) {
/* not enough space for another interface_name:queue_id pair */ /* not enough space for another interface_name:queue_id pair */
if ((PAGE_SIZE - res) > 10) if ((PAGE_SIZE - res) > 10)
...@@ -1498,6 +1496,7 @@ static ssize_t bonding_show_queue_id(struct device *d, ...@@ -1498,6 +1496,7 @@ static ssize_t bonding_show_queue_id(struct device *d,
if (res) if (res)
buf[res-1] = '\n'; /* eat the leftover space */ buf[res-1] = '\n'; /* eat the leftover space */
rtnl_unlock(); rtnl_unlock();
return res; return res;
} }
...@@ -1512,7 +1511,7 @@ static ssize_t bonding_store_queue_id(struct device *d, ...@@ -1512,7 +1511,7 @@ static ssize_t bonding_store_queue_id(struct device *d,
struct slave *slave, *update_slave; struct slave *slave, *update_slave;
struct bonding *bond = to_bond(d); struct bonding *bond = to_bond(d);
u16 qid; u16 qid;
int i, ret = count; int ret = count;
char *delim; char *delim;
struct net_device *sdev = NULL; struct net_device *sdev = NULL;
...@@ -1547,7 +1546,7 @@ static ssize_t bonding_store_queue_id(struct device *d, ...@@ -1547,7 +1546,7 @@ static ssize_t bonding_store_queue_id(struct device *d,
/* Search for thes slave and check for duplicate qids */ /* Search for thes slave and check for duplicate qids */
update_slave = NULL; update_slave = NULL;
bond_for_each_slave(bond, slave, i) { bond_for_each_slave(bond, slave) {
if (sdev == slave->dev) if (sdev == slave->dev)
/* /*
* We don't need to check the matching * We don't need to check the matching
...@@ -1599,8 +1598,8 @@ static ssize_t bonding_store_slaves_active(struct device *d, ...@@ -1599,8 +1598,8 @@ static ssize_t bonding_store_slaves_active(struct device *d,
struct device_attribute *attr, struct device_attribute *attr,
const char *buf, size_t count) const char *buf, size_t count)
{ {
int i, new_value, ret = count;
struct bonding *bond = to_bond(d); struct bonding *bond = to_bond(d);
int new_value, ret = count;
struct slave *slave; struct slave *slave;
if (sscanf(buf, "%d", &new_value) != 1) { if (sscanf(buf, "%d", &new_value) != 1) {
...@@ -1623,7 +1622,7 @@ static ssize_t bonding_store_slaves_active(struct device *d, ...@@ -1623,7 +1622,7 @@ static ssize_t bonding_store_slaves_active(struct device *d,
} }
read_lock(&bond->lock); read_lock(&bond->lock);
bond_for_each_slave(bond, slave, i) { bond_for_each_slave(bond, slave) {
if (!bond_is_active_slave(slave)) { if (!bond_is_active_slave(slave)) {
if (new_value) if (new_value)
slave->inactive = 0; slave->inactive = 0;
......
...@@ -71,6 +71,28 @@ ...@@ -71,6 +71,28 @@
set_fs(fs); \ set_fs(fs); \
res; }) res; })
/* slave list primitives */
#define bond_to_slave(ptr) list_entry(ptr, struct slave, list)
/* IMPORTANT: bond_first/last_slave can return NULL in case of an empty list */
#define bond_first_slave(bond) \
list_first_entry_or_null(&(bond)->slave_list, struct slave, list)
#define bond_last_slave(bond) \
(list_empty(&(bond)->slave_list) ? NULL : \
bond_to_slave((bond)->slave_list.prev))
#define bond_is_first_slave(bond, pos) ((pos)->list.prev == &(bond)->slave_list)
#define bond_is_last_slave(bond, pos) ((pos)->list.next == &(bond)->slave_list)
/* Since bond_first/last_slave can return NULL, these can return NULL too */
#define bond_next_slave(bond, pos) \
(bond_is_last_slave(bond, pos) ? bond_first_slave(bond) : \
bond_to_slave((pos)->list.next))
#define bond_prev_slave(bond, pos) \
(bond_is_first_slave(bond, pos) ? bond_last_slave(bond) : \
bond_to_slave((pos)->list.prev))
/** /**
* bond_for_each_slave_from - iterate the slaves list from a starting point * bond_for_each_slave_from - iterate the slaves list from a starting point
* @bond: the bond holding this list. * @bond: the bond holding this list.
...@@ -80,37 +102,29 @@ ...@@ -80,37 +102,29 @@
* *
* Caller must hold bond->lock * Caller must hold bond->lock
*/ */
#define bond_for_each_slave_from(bond, pos, cnt, start) \ #define bond_for_each_slave_from(bond, pos, cnt, start) \
for (cnt = 0, pos = start; \ for (cnt = 0, pos = start; pos && cnt < (bond)->slave_cnt; \
cnt < (bond)->slave_cnt; \ cnt++, pos = bond_next_slave(bond, pos))
cnt++, pos = (pos)->next)
/** /**
* bond_for_each_slave_from_to - iterate the slaves list from start point to stop point * bond_for_each_slave - iterate over all slaves
* @bond: the bond holding this list. * @bond: the bond holding this list
* @pos: current slave. * @pos: current slave
* @cnt: counter for number max of moves
* @start: start point.
* @stop: stop point.
* *
* Caller must hold bond->lock * Caller must hold bond->lock
*/ */
#define bond_for_each_slave_from_to(bond, pos, cnt, start, stop) \ #define bond_for_each_slave(bond, pos) \
for (cnt = 0, pos = start; \ list_for_each_entry(pos, &(bond)->slave_list, list)
((cnt < (bond)->slave_cnt) && (pos != (stop)->next)); \
cnt++, pos = (pos)->next)
/** /**
* bond_for_each_slave - iterate the slaves list from head * bond_for_each_slave_reverse - iterate in reverse from a given position
* @bond: the bond holding this list. * @bond: the bond holding this list
* @pos: current slave. * @pos: slave to continue from
* @cnt: counter for max number of moves
* *
* Caller must hold bond->lock * Caller must hold bond->lock
*/ */
#define bond_for_each_slave(bond, pos, cnt) \ #define bond_for_each_slave_continue_reverse(bond, pos) \
bond_for_each_slave_from(bond, pos, cnt, (bond)->first_slave) list_for_each_entry_continue_reverse(pos, &(bond)->slave_list, list)
#ifdef CONFIG_NET_POLL_CONTROLLER #ifdef CONFIG_NET_POLL_CONTROLLER
extern atomic_t netpoll_block_tx; extern atomic_t netpoll_block_tx;
...@@ -174,8 +188,7 @@ struct vlan_entry { ...@@ -174,8 +188,7 @@ struct vlan_entry {
struct slave { struct slave {
struct net_device *dev; /* first - useful for panic debug */ struct net_device *dev; /* first - useful for panic debug */
struct slave *next; struct list_head list;
struct slave *prev;
struct bonding *bond; /* our master */ struct bonding *bond; /* our master */
int delay; int delay;
unsigned long jiffies; unsigned long jiffies;
...@@ -215,7 +228,7 @@ struct slave { ...@@ -215,7 +228,7 @@ struct slave {
*/ */
struct bonding { struct bonding {
struct net_device *dev; /* first - useful for panic debug */ struct net_device *dev; /* first - useful for panic debug */
struct slave *first_slave; struct list_head slave_list;
struct slave *curr_active_slave; struct slave *curr_active_slave;
struct slave *current_arp_slave; struct slave *current_arp_slave;
struct slave *primary_slave; struct slave *primary_slave;
...@@ -270,13 +283,10 @@ static inline struct slave *bond_get_slave_by_dev(struct bonding *bond, ...@@ -270,13 +283,10 @@ static inline struct slave *bond_get_slave_by_dev(struct bonding *bond,
struct net_device *slave_dev) struct net_device *slave_dev)
{ {
struct slave *slave = NULL; struct slave *slave = NULL;
int i;
bond_for_each_slave(bond, slave, i) { bond_for_each_slave(bond, slave)
if (slave->dev == slave_dev) { if (slave->dev == slave_dev)
return slave; return slave;
}
}
return NULL; return NULL;
} }
...@@ -477,10 +487,9 @@ static inline void bond_destroy_proc_dir(struct bond_net *bn) ...@@ -477,10 +487,9 @@ static inline void bond_destroy_proc_dir(struct bond_net *bn)
static inline struct slave *bond_slave_has_mac(struct bonding *bond, static inline struct slave *bond_slave_has_mac(struct bonding *bond,
const u8 *mac) const u8 *mac)
{ {
int i = 0;
struct slave *tmp; struct slave *tmp;
bond_for_each_slave(bond, tmp, i) bond_for_each_slave(bond, tmp)
if (ether_addr_equal_64bits(mac, tmp->dev->dev_addr)) if (ether_addr_equal_64bits(mac, tmp->dev->dev_addr))
return tmp; return tmp;
......
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