* [PATCH 0/4] bonding: Fix workqueue manipulation and lock taking
@ 2008-01-15 6:36 Makito SHIOKAWA
2008-01-15 6:36 ` [PATCH 1/4] bonding: Fix work initing and cancelling Makito SHIOKAWA
` (3 more replies)
0 siblings, 4 replies; 23+ messages in thread
From: Makito SHIOKAWA @ 2008-01-15 6:36 UTC (permalink / raw)
To: netdev
These patches fix some workqueue manipulation and lock taking in bonding driver.
PATCH 1/4 through PATCH 3/4 are on workqueue manipulation, PATCH 4/4 is on lock taking, and each patch are logically independent. Patches are for latest netdev-2.6 git.
--
Makito SHIOKAWA
MIRACLE LINUX CORPORATION
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH 1/4] bonding: Fix work initing and cancelling
2008-01-15 6:36 [PATCH 0/4] bonding: Fix workqueue manipulation and lock taking Makito SHIOKAWA
@ 2008-01-15 6:36 ` Makito SHIOKAWA
2008-01-15 10:56 ` Jarek Poplawski
2008-01-15 6:36 ` [PATCH 2/4] bonding: Add destroy_workqueue() to bond device destroying process Makito SHIOKAWA
` (2 subsequent siblings)
3 siblings, 1 reply; 23+ messages in thread
From: Makito SHIOKAWA @ 2008-01-15 6:36 UTC (permalink / raw)
To: netdev; +Cc: Makito SHIOKAWA
[-- Attachment #1: bonding-fix-work-manipulation-in-sysfs.patch --]
[-- Type: text/plain, Size: 7400 bytes --]
delayed_work_pending() is used to check whether work is being queued or not,
when queueing or cancelling corresponding work. However,
delayed_work_pending() returns 0 when work is just running, and in that case,
work_struct will be destroyed or work won't be cancelled. So remove all
delayed_work_pending(), and move all INIT_DELAYED_WORK to bonding init
process, just queue or cancel work. For this purpose, arp_work is divided into
two works.
Signed-off-by: Makito SHIOKAWA <mshiokawa@miraclelinux.com>
---
drivers/net/bonding/bond_main.c | 46 ++++++++++++++++++++------------------
drivers/net/bonding/bond_sysfs.c | 36 +++++++++--------------------
drivers/net/bonding/bonding.h | 3 +-
3 files changed, 39 insertions(+), 46 deletions(-)
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -2692,7 +2692,7 @@ out:
void bond_loadbalance_arp_mon(struct work_struct *work)
{
struct bonding *bond = container_of(work, struct bonding,
- arp_work.work);
+ lb_arp_work.work);
struct slave *slave, *oldcurrent;
int do_failover = 0;
int delta_in_ticks;
@@ -2803,7 +2803,7 @@ void bond_loadbalance_arp_mon(struct wor
re_arm:
if (bond->params.arp_interval)
- queue_delayed_work(bond->wq, &bond->arp_work, delta_in_ticks);
+ queue_delayed_work(bond->wq, &bond->lb_arp_work, delta_in_ticks);
out:
read_unlock(&bond->lock);
}
@@ -2826,7 +2826,7 @@ out:
void bond_activebackup_arp_mon(struct work_struct *work)
{
struct bonding *bond = container_of(work, struct bonding,
- arp_work.work);
+ ab_arp_work.work);
struct slave *slave;
int delta_in_ticks;
int i;
@@ -3060,7 +3060,7 @@ void bond_activebackup_arp_mon(struct wo
re_arm:
if (bond->params.arp_interval) {
- queue_delayed_work(bond->wq, &bond->arp_work, delta_in_ticks);
+ queue_delayed_work(bond->wq, &bond->ab_arp_work, delta_in_ticks);
}
out:
read_unlock(&bond->lock);
@@ -3679,30 +3679,23 @@ static int bond_open(struct net_device *
return -1;
}
- INIT_DELAYED_WORK(&bond->alb_work, bond_alb_monitor);
queue_delayed_work(bond->wq, &bond->alb_work, 0);
}
if (bond->params.miimon) { /* link check interval, in milliseconds. */
- INIT_DELAYED_WORK(&bond->mii_work, bond_mii_monitor);
queue_delayed_work(bond->wq, &bond->mii_work, 0);
}
if (bond->params.arp_interval) { /* arp interval, in milliseconds. */
if (bond->params.mode == BOND_MODE_ACTIVEBACKUP)
- INIT_DELAYED_WORK(&bond->arp_work,
- bond_activebackup_arp_mon);
+ queue_delayed_work(bond->wq, &bond->ab_arp_work, 0);
else
- INIT_DELAYED_WORK(&bond->arp_work,
- bond_loadbalance_arp_mon);
-
- queue_delayed_work(bond->wq, &bond->arp_work, 0);
+ queue_delayed_work(bond->wq, &bond->lb_arp_work, 0);
if (bond->params.arp_validate)
bond_register_arp(bond);
}
if (bond->params.mode == BOND_MODE_8023AD) {
- INIT_DELAYED_WORK(&bond->ad_work, bond_3ad_state_machine_handler);
queue_delayed_work(bond->wq, &bond->ad_work, 0);
/* register to receive LACPDUs */
bond_register_lacpdu(bond);
@@ -3736,7 +3729,10 @@ static int bond_close(struct net_device
}
if (bond->params.arp_interval) { /* arp interval, in milliseconds. */
- cancel_delayed_work(&bond->arp_work);
+ if (bond->params.mode == BOND_MODE_ACTIVEBACKUP)
+ cancel_delayed_work(&bond->ab_arp_work);
+ else
+ cancel_delayed_work(&bond->lb_arp_work);
}
switch (bond->params.mode) {
@@ -4416,6 +4412,12 @@ static int bond_init(struct net_device *
if (!bond->wq)
return -ENOMEM;
+ INIT_DELAYED_WORK(&bond->alb_work, bond_alb_monitor);
+ INIT_DELAYED_WORK(&bond->mii_work, bond_mii_monitor);
+ INIT_DELAYED_WORK(&bond->ab_arp_work, bond_activebackup_arp_mon);
+ INIT_DELAYED_WORK(&bond->lb_arp_work, bond_loadbalance_arp_mon);
+ INIT_DELAYED_WORK(&bond->ad_work, bond_3ad_state_machine_handler);
+
/* Initialize pointers */
bond->first_slave = NULL;
bond->curr_active_slave = NULL;
@@ -4498,18 +4500,20 @@ static void bond_work_cancel_all(struct
bond->kill_timers = 1;
write_unlock_bh(&bond->lock);
- if (bond->params.miimon && delayed_work_pending(&bond->mii_work))
+ if (bond->params.miimon)
cancel_delayed_work(&bond->mii_work);
- if (bond->params.arp_interval && delayed_work_pending(&bond->arp_work))
- cancel_delayed_work(&bond->arp_work);
+ if (bond->params.arp_interval) {
+ if (bond->params.mode == BOND_MODE_ACTIVEBACKUP)
+ cancel_delayed_work(&bond->ab_arp_work);
+ else
+ cancel_delayed_work(&bond->lb_arp_work);
+ }
- if (bond->params.mode == BOND_MODE_ALB &&
- delayed_work_pending(&bond->alb_work))
+ if (bond->params.mode == BOND_MODE_ALB)
cancel_delayed_work(&bond->alb_work);
- if (bond->params.mode == BOND_MODE_8023AD &&
- delayed_work_pending(&bond->ad_work))
+ if (bond->params.mode == BOND_MODE_8023AD)
cancel_delayed_work(&bond->ad_work);
}
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -643,10 +643,8 @@ static ssize_t bonding_store_arp_interva
"%s Disabling MII monitoring.\n",
bond->dev->name, bond->dev->name);
bond->params.miimon = 0;
- if (delayed_work_pending(&bond->mii_work)) {
- cancel_delayed_work(&bond->mii_work);
- flush_workqueue(bond->wq);
- }
+ cancel_delayed_work(&bond->mii_work);
+ flush_workqueue(bond->wq);
}
if (!bond->params.arp_targets[0]) {
printk(KERN_INFO DRV_NAME
@@ -660,16 +658,10 @@ static ssize_t bonding_store_arp_interva
* timer will get fired off when the open function
* is called.
*/
- if (!delayed_work_pending(&bond->arp_work)) {
- if (bond->params.mode == BOND_MODE_ACTIVEBACKUP)
- INIT_DELAYED_WORK(&bond->arp_work,
- bond_activebackup_arp_mon);
- else
- INIT_DELAYED_WORK(&bond->arp_work,
- bond_loadbalance_arp_mon);
-
- queue_delayed_work(bond->wq, &bond->arp_work, 0);
- }
+ if (bond->params.mode == BOND_MODE_ACTIVEBACKUP)
+ queue_delayed_work(bond->wq, &bond->ab_arp_work, 0);
+ else
+ queue_delayed_work(bond->wq, &bond->lb_arp_work, 0);
}
out:
@@ -1022,10 +1014,11 @@ static ssize_t bonding_store_miimon(stru
bond->params.arp_validate =
BOND_ARP_VALIDATE_NONE;
}
- if (delayed_work_pending(&bond->arp_work)) {
- cancel_delayed_work(&bond->arp_work);
- flush_workqueue(bond->wq);
- }
+ if (bond->params.mode == BOND_MODE_ACTIVEBACKUP)
+ cancel_delayed_work(&bond->ab_arp_work);
+ else
+ cancel_delayed_work(&bond->lb_arp_work);
+ flush_workqueue(bond->wq);
}
if (bond->dev->flags & IFF_UP) {
@@ -1034,12 +1027,7 @@ static ssize_t bonding_store_miimon(stru
* timer will get fired off when the open function
* is called.
*/
- if (!delayed_work_pending(&bond->mii_work)) {
- INIT_DELAYED_WORK(&bond->mii_work,
- bond_mii_monitor);
- queue_delayed_work(bond->wq,
- &bond->mii_work, 0);
- }
+ queue_delayed_work(bond->wq, &bond->mii_work, 0);
}
}
out:
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -206,7 +206,8 @@ struct bonding {
struct packet_type arp_mon_pt;
struct workqueue_struct *wq;
struct delayed_work mii_work;
- struct delayed_work arp_work;
+ struct delayed_work ab_arp_work;
+ struct delayed_work lb_arp_work;
struct delayed_work alb_work;
struct delayed_work ad_work;
};
--
Makito SHIOKAWA
MIRACLE LINUX CORPORATION
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH 2/4] bonding: Add destroy_workqueue() to bond device destroying process
2008-01-15 6:36 [PATCH 0/4] bonding: Fix workqueue manipulation and lock taking Makito SHIOKAWA
2008-01-15 6:36 ` [PATCH 1/4] bonding: Fix work initing and cancelling Makito SHIOKAWA
@ 2008-01-15 6:36 ` Makito SHIOKAWA
2008-01-15 6:36 ` [PATCH 3/4] bonding: Fix work rearming Makito SHIOKAWA
2008-01-15 6:36 ` [PATCH 4/4] bonding: Fix some RTNL taking Makito SHIOKAWA
3 siblings, 0 replies; 23+ messages in thread
From: Makito SHIOKAWA @ 2008-01-15 6:36 UTC (permalink / raw)
To: netdev; +Cc: Makito SHIOKAWA
[-- Attachment #1: bonding-guarantee-destroy-work.patch --]
[-- Type: text/plain, Size: 6186 bytes --]
There is no destroy_workqueue() in bond device destroying process, therefore
worker thread will remain even if bond device is destroyed. So add
destroy_workqueue(), and also, ensure all works are canceled before
destroy_workqueue() is called.
Signed-off-by: Makito SHIOKAWA <mshiokawa@miraclelinux.com>
---
drivers/net/bonding/bond_main.c | 72 +++++++++++++++++++-------------------
drivers/net/bonding/bond_sysfs.c | 9 ++++
drivers/net/bonding/bonding.h | 5 ++
3 files changed, 48 insertions(+), 38 deletions(-)
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -190,7 +190,6 @@ struct bond_parm_tbl arp_validate_tbl[]
/*-------------------------- Forward declarations ---------------------------*/
static void bond_send_gratuitous_arp(struct bonding *bond);
-static void bond_deinit(struct net_device *bond_dev);
/*---------------------------- General routines -----------------------------*/
@@ -862,7 +861,7 @@ static void bond_resend_igmp_join_reques
/*
* Totally destroys the mc_list in bond
*/
-static void bond_mc_list_destroy(struct bonding *bond)
+void bond_mc_list_destroy(struct bonding *bond)
{
struct dev_mc_list *dmi;
@@ -1875,7 +1874,7 @@ int bond_release_and_destroy(struct net
/*
* This function releases all slaves.
*/
-static int bond_release_all(struct net_device *bond_dev)
+int bond_release_all(struct net_device *bond_dev)
{
struct bonding *bond = bond_dev->priv;
struct slave *slave;
@@ -4392,6 +4391,25 @@ static const struct ethtool_ops bond_eth
.get_drvinfo = bond_ethtool_get_drvinfo,
};
+/* Caller must not hold rtnl_lock */
+void bond_work_cancel_all(struct bonding *bond)
+{
+ /* ensure all works are stopped */
+ cancel_delayed_work_sync(&bond->alb_work);
+ cancel_delayed_work_sync(&bond->mii_work);
+ cancel_delayed_work_sync(&bond->ab_arp_work);
+ cancel_delayed_work_sync(&bond->lb_arp_work);
+ cancel_delayed_work_sync(&bond->ad_work);
+}
+
+static void bond_free_netdev(struct net_device *dev)
+{
+ struct bonding *bond = netdev_priv(dev);
+
+ destroy_workqueue(bond->wq);
+ free_netdev(dev);
+}
+
/*
* Does not allocate but creates a /proc entry.
* Allowed to fail.
@@ -4441,7 +4459,7 @@ static int bond_init(struct net_device *
bond_set_mode_ops(bond, bond->params.mode);
- bond_dev->destructor = free_netdev;
+ bond_dev->destructor = bond_free_netdev;
/* Initialize the device options */
bond_dev->tx_queue_len = 0;
@@ -4483,7 +4501,7 @@ static int bond_init(struct net_device *
/* De-initialize device specific data.
* Caller must hold rtnl_lock.
*/
-static void bond_deinit(struct net_device *bond_dev)
+void bond_deinit(struct net_device *bond_dev)
{
struct bonding *bond = bond_dev->priv;
@@ -4494,29 +4512,6 @@ static void bond_deinit(struct net_devic
#endif
}
-static void bond_work_cancel_all(struct bonding *bond)
-{
- write_lock_bh(&bond->lock);
- bond->kill_timers = 1;
- write_unlock_bh(&bond->lock);
-
- if (bond->params.miimon)
- cancel_delayed_work(&bond->mii_work);
-
- if (bond->params.arp_interval) {
- if (bond->params.mode == BOND_MODE_ACTIVEBACKUP)
- cancel_delayed_work(&bond->ab_arp_work);
- else
- cancel_delayed_work(&bond->lb_arp_work);
- }
-
- if (bond->params.mode == BOND_MODE_ALB)
- cancel_delayed_work(&bond->alb_work);
-
- if (bond->params.mode == BOND_MODE_8023AD)
- cancel_delayed_work(&bond->ad_work);
-}
-
/* Unregister and free all bond devices.
* Caller must hold rtnl_lock.
*/
@@ -4527,11 +4522,14 @@ static void bond_free_all(void)
list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list) {
struct net_device *bond_dev = bond->dev;
+ bond_deinit(bond_dev);
+ rtnl_unlock();
bond_work_cancel_all(bond);
+ rtnl_lock();
bond_mc_list_destroy(bond);
/* Release the bonded slaves */
bond_release_all(bond_dev);
- bond_deinit(bond_dev);
+ bond_destroy_sysfs_entry(bond);
unregister_netdevice(bond_dev);
}
@@ -4921,8 +4919,16 @@ int bond_create(char *name, struct bond_
out_bond:
bond_deinit(bond_dev);
+ if (*newbond)
+ unregister_netdevice(bond_dev);
+ else {
+ rtnl_unlock();
+ bond_work_cancel_all(netdev_priv(bond_dev));
+ rtnl_lock();
+ destroy_workqueue(((struct bonding *)netdev_priv(bond_dev))->wq);
out_netdev:
- free_netdev(bond_dev);
+ free_netdev(bond_dev);
+ }
out_rtnl:
rtnl_unlock();
return res;
@@ -4932,7 +4938,6 @@ static int __init bonding_init(void)
{
int i;
int res;
- struct bonding *bond, *nxt;
printk(KERN_INFO "%s", version);
@@ -4959,11 +4964,6 @@ static int __init bonding_init(void)
goto out;
err:
- list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list) {
- bond_work_cancel_all(bond);
- destroy_workqueue(bond->wq);
- }
-
rtnl_lock();
bond_free_all();
bond_destroy_sysfs();
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -163,7 +163,14 @@ static ssize_t bonding_store_bonds(struc
printk(KERN_INFO DRV_NAME
": %s is being deleted...\n",
bond->dev->name);
- bond_destroy(bond);
+ bond_deinit(bond->dev);
+ rtnl_unlock();
+ bond_work_cancel_all(bond);
+ rtnl_lock();
+ bond_mc_list_destroy(bond);
+ bond_release_all(bond->dev);
+ bond_destroy_sysfs_entry(bond);
+ unregister_netdevice(bond->dev);
rtnl_unlock();
goto out;
}
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -301,7 +301,10 @@ static inline void bond_unset_master_alb
struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr);
int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev);
int bond_create(char *name, struct bond_params *params, struct bonding **newbond);
-void bond_destroy(struct bonding *bond);
+void bond_deinit(struct net_device *bond_dev);
+void bond_work_cancel_all(struct bonding *bond);
+void bond_mc_list_destroy(struct bonding *bond);
+int bond_release_all(struct net_device *bond_dev);
int bond_release_and_destroy(struct net_device *bond_dev, struct net_device *slave_dev);
int bond_create_sysfs(void);
void bond_destroy_sysfs(void);
--
Makito SHIOKAWA
MIRACLE LINUX CORPORATION
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH 3/4] bonding: Fix work rearming
2008-01-15 6:36 [PATCH 0/4] bonding: Fix workqueue manipulation and lock taking Makito SHIOKAWA
2008-01-15 6:36 ` [PATCH 1/4] bonding: Fix work initing and cancelling Makito SHIOKAWA
2008-01-15 6:36 ` [PATCH 2/4] bonding: Add destroy_workqueue() to bond device destroying process Makito SHIOKAWA
@ 2008-01-15 6:36 ` Makito SHIOKAWA
2008-01-15 9:05 ` Jarek Poplawski
2008-01-15 6:36 ` [PATCH 4/4] bonding: Fix some RTNL taking Makito SHIOKAWA
3 siblings, 1 reply; 23+ messages in thread
From: Makito SHIOKAWA @ 2008-01-15 6:36 UTC (permalink / raw)
To: netdev; +Cc: Makito SHIOKAWA
[-- Attachment #1: bonding-fix-monitor-rearming.patch --]
[-- Type: text/plain, Size: 706 bytes --]
Change code not to rearm bond_mii_monitor() when value 0 is set for miimon.
Signed-off-by: Makito SHIOKAWA <mshiokawa@miraclelinux.com>
---
drivers/net/bonding/bond_main.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -2388,7 +2388,8 @@ void bond_mii_monitor(struct work_struct
delay = ((bond->params.miimon * HZ) / 1000) ? : 1;
read_unlock(&bond->lock);
- queue_delayed_work(bond->wq, &bond->mii_work, delay);
+ if (bond->params.miimon)
+ queue_delayed_work(bond->wq, &bond->mii_work, delay);
}
static __be32 bond_glean_dev_ip(struct net_device *dev)
--
Makito SHIOKAWA
MIRACLE LINUX CORPORATION
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH 4/4] bonding: Fix some RTNL taking
2008-01-15 6:36 [PATCH 0/4] bonding: Fix workqueue manipulation and lock taking Makito SHIOKAWA
` (2 preceding siblings ...)
2008-01-15 6:36 ` [PATCH 3/4] bonding: Fix work rearming Makito SHIOKAWA
@ 2008-01-15 6:36 ` Makito SHIOKAWA
2008-01-16 12:44 ` Jarek Poplawski
3 siblings, 1 reply; 23+ messages in thread
From: Makito SHIOKAWA @ 2008-01-15 6:36 UTC (permalink / raw)
To: netdev; +Cc: Makito SHIOKAWA
[-- Attachment #1: bonding-fix-some-rtnl-taking.patch --]
[-- Type: text/plain, Size: 3810 bytes --]
Fix some RTNL lock taking:
* RTNL (mutex; may sleep) must not be taken under read_lock (spinlock; must be
atomic). However, RTNL is taken under read_lock in bond_loadbalance_arp_mon()
and bond_activebackup_arp_mon(). So change code to take RTNL outside of read_lock.
* rtnl_unlock() calls netdev_run_todo() which takes net_todo_run_mutex, and
rtnl_unlock() is called under read_lock in bond_mii_monitor(). So for the same
reason as above, change code to call rtnl_unlock() outside of read_lock.
Signed-off-by: Makito SHIOKAWA <mshiokawa@miraclelinux.com>
---
drivers/net/bonding/bond_main.c | 24 ++++++++++--------------
1 file changed, 10 insertions(+), 14 deletions(-)
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -2372,6 +2372,7 @@ void bond_mii_monitor(struct work_struct
struct bonding *bond = container_of(work, struct bonding,
mii_work.work);
unsigned long delay;
+ int need_unlock = 0;
read_lock(&bond->lock);
if (bond->kill_timers) {
@@ -2383,13 +2384,16 @@ void bond_mii_monitor(struct work_struct
rtnl_lock();
read_lock(&bond->lock);
__bond_mii_monitor(bond, 1);
- rtnl_unlock();
+ need_unlock = 1;
}
delay = ((bond->params.miimon * HZ) / 1000) ? : 1;
- read_unlock(&bond->lock);
if (bond->params.miimon)
queue_delayed_work(bond->wq, &bond->mii_work, delay);
+ read_unlock(&bond->lock);
+ /* rtnl_unlock() may sleep, so call it after read_unlock() */
+ if (need_unlock)
+ rtnl_unlock();
}
static __be32 bond_glean_dev_ip(struct net_device *dev)
@@ -2698,6 +2702,7 @@ void bond_loadbalance_arp_mon(struct wor
int delta_in_ticks;
int i;
+ rtnl_lock();
read_lock(&bond->lock);
delta_in_ticks = (bond->params.arp_interval * HZ) / 1000;
@@ -2791,14 +2796,11 @@ void bond_loadbalance_arp_mon(struct wor
}
if (do_failover) {
- rtnl_lock();
write_lock_bh(&bond->curr_slave_lock);
bond_select_active_slave(bond);
write_unlock_bh(&bond->curr_slave_lock);
- rtnl_unlock();
-
}
re_arm:
@@ -2806,6 +2808,7 @@ re_arm:
queue_delayed_work(bond->wq, &bond->lb_arp_work, delta_in_ticks);
out:
read_unlock(&bond->lock);
+ rtnl_unlock();
}
/*
@@ -2831,6 +2834,7 @@ void bond_activebackup_arp_mon(struct wo
int delta_in_ticks;
int i;
+ rtnl_lock();
read_lock(&bond->lock);
delta_in_ticks = (bond->params.arp_interval * HZ) / 1000;
@@ -2855,8 +2859,6 @@ void bond_activebackup_arp_mon(struct wo
slave->link = BOND_LINK_UP;
- rtnl_lock();
-
write_lock_bh(&bond->curr_slave_lock);
if ((!bond->curr_active_slave) &&
@@ -2892,7 +2894,6 @@ void bond_activebackup_arp_mon(struct wo
}
write_unlock_bh(&bond->curr_slave_lock);
- rtnl_unlock();
}
} else {
read_lock(&bond->curr_slave_lock);
@@ -2962,7 +2963,6 @@ void bond_activebackup_arp_mon(struct wo
bond->dev->name,
slave->dev->name);
- rtnl_lock();
write_lock_bh(&bond->curr_slave_lock);
bond_select_active_slave(bond);
@@ -2970,8 +2970,6 @@ void bond_activebackup_arp_mon(struct wo
write_unlock_bh(&bond->curr_slave_lock);
- rtnl_unlock();
-
bond->current_arp_slave = slave;
if (slave) {
@@ -2989,13 +2987,10 @@ void bond_activebackup_arp_mon(struct wo
bond->primary_slave->dev->name);
/* primary is up so switch to it */
- rtnl_lock();
write_lock_bh(&bond->curr_slave_lock);
bond_change_active_slave(bond, bond->primary_slave);
write_unlock_bh(&bond->curr_slave_lock);
- rtnl_unlock();
-
slave = bond->primary_slave;
slave->jiffies = jiffies;
} else {
@@ -3064,6 +3059,7 @@ re_arm:
}
out:
read_unlock(&bond->lock);
+ rtnl_unlock();
}
/*------------------------------ proc/seq_file-------------------------------*/
--
Makito SHIOKAWA
MIRACLE LINUX CORPORATION
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 3/4] bonding: Fix work rearming
2008-01-15 6:36 ` [PATCH 3/4] bonding: Fix work rearming Makito SHIOKAWA
@ 2008-01-15 9:05 ` Jarek Poplawski
2008-01-16 3:19 ` Makito SHIOKAWA
2008-01-16 3:28 ` Makito SHIOKAWA
0 siblings, 2 replies; 23+ messages in thread
From: Jarek Poplawski @ 2008-01-15 9:05 UTC (permalink / raw)
To: Makito SHIOKAWA; +Cc: netdev
On 15-01-2008 07:36, Makito SHIOKAWA wrote:
> Change code not to rearm bond_mii_monitor() when value 0 is set for miimon.
>
> Signed-off-by: Makito SHIOKAWA <mshiokawa@miraclelinux.com>
> ---
> drivers/net/bonding/bond_main.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> --- a/drivers/net/bonding/bond_main.c
> +++ b/drivers/net/bonding/bond_main.c
> @@ -2388,7 +2388,8 @@ void bond_mii_monitor(struct work_struct
>
> delay = ((bond->params.miimon * HZ) / 1000) ? : 1;
> read_unlock(&bond->lock);
> - queue_delayed_work(bond->wq, &bond->mii_work, delay);
> + if (bond->params.miimon)
> + queue_delayed_work(bond->wq, &bond->mii_work, delay);
> }
Maybe I miss something, but is this bond_mii_monitor() function
supposed to be ever started if (!bond->params.miimon)? (IOW: isn't
it enough to control this where the parameter is changed only?)
Regards,
Jarek P.
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 1/4] bonding: Fix work initing and cancelling
2008-01-15 6:36 ` [PATCH 1/4] bonding: Fix work initing and cancelling Makito SHIOKAWA
@ 2008-01-15 10:56 ` Jarek Poplawski
2008-01-16 5:17 ` Makito SHIOKAWA
0 siblings, 1 reply; 23+ messages in thread
From: Jarek Poplawski @ 2008-01-15 10:56 UTC (permalink / raw)
To: Makito SHIOKAWA; +Cc: netdev
On 15-01-2008 07:36, Makito SHIOKAWA wrote:
...
> --- a/drivers/net/bonding/bond_sysfs.c
> +++ b/drivers/net/bonding/bond_sysfs.c
> @@ -643,10 +643,8 @@ static ssize_t bonding_store_arp_interva
> "%s Disabling MII monitoring.\n",
> bond->dev->name, bond->dev->name);
> bond->params.miimon = 0;
> - if (delayed_work_pending(&bond->mii_work)) {
> - cancel_delayed_work(&bond->mii_work);
> - flush_workqueue(bond->wq);
> - }
> + cancel_delayed_work(&bond->mii_work);
> + flush_workqueue(bond->wq);
I wonder why don't you use cancel_delayed_work_sync() here (and in a
few other places), like in bond_work_cancel_all() from patch 2/4?
Regards,
Jarek P.
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 3/4] bonding: Fix work rearming
2008-01-15 9:05 ` Jarek Poplawski
@ 2008-01-16 3:19 ` Makito SHIOKAWA
2008-01-16 13:36 ` Jarek Poplawski
2008-01-16 3:28 ` Makito SHIOKAWA
1 sibling, 1 reply; 23+ messages in thread
From: Makito SHIOKAWA @ 2008-01-16 3:19 UTC (permalink / raw)
To: Jarek Poplawski; +Cc: netdev
This patch is supposing a case that bond_mii_monitor() is invoked in
bond_open(), and after that, 0 is set to miimon via sysfs (see same place on
other monitors).
Though message in bonding_store_miimon() says miimon value 1-INT_MAX rejected,
but it looks like 0 can be accepted and monitor must be stopped in that case.
>> Change code not to rearm bond_mii_monitor() when value 0 is set for miimon.
>>
>> Signed-off-by: Makito SHIOKAWA <mshiokawa@miraclelinux.com>
>> ---
>> drivers/net/bonding/bond_main.c | 3 ++-
>> 1 file changed, 2 insertions(+), 1 deletion(-)
>>
>> --- a/drivers/net/bonding/bond_main.c
>> +++ b/drivers/net/bonding/bond_main.c
>> @@ -2388,7 +2388,8 @@ void bond_mii_monitor(struct work_struct
>>
>> delay = ((bond->params.miimon * HZ) / 1000) ? : 1;
>> read_unlock(&bond->lock);
>> - queue_delayed_work(bond->wq, &bond->mii_work, delay);
>> + if (bond->params.miimon)
>> + queue_delayed_work(bond->wq, &bond->mii_work, delay);
>> }
>
> Maybe I miss something, but is this bond_mii_monitor() function
> supposed to be ever started if (!bond->params.miimon)? (IOW: isn't
> it enough to control this where the parameter is changed only?)
>
> Regards,
> Jarek P.
--
Makito SHIOKAWA
MIRACLE LINUX CORPORATION
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 3/4] bonding: Fix work rearming
2008-01-15 9:05 ` Jarek Poplawski
2008-01-16 3:19 ` Makito SHIOKAWA
@ 2008-01-16 3:28 ` Makito SHIOKAWA
1 sibling, 0 replies; 23+ messages in thread
From: Makito SHIOKAWA @ 2008-01-16 3:28 UTC (permalink / raw)
To: Jarek Poplawski; +Cc: netdev
> Though message in bonding_store_miimon() says miimon value 1-INT_MAX
> rejected, but it looks like 0 can be accepted and monitor must be
> stopped in that case.
=> miimon value *not in range* 1-INT_MAX
--
Makito SHIOKAWA
MIRACLE LINUX CORPORATION
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 1/4] bonding: Fix work initing and cancelling
2008-01-15 10:56 ` Jarek Poplawski
@ 2008-01-16 5:17 ` Makito SHIOKAWA
0 siblings, 0 replies; 23+ messages in thread
From: Makito SHIOKAWA @ 2008-01-16 5:17 UTC (permalink / raw)
To: Jarek Poplawski; +Cc: netdev, Makito SHIOKAWA
> I wonder why don't you use cancel_delayed_work_sync() here (and in a
> few other places), like in bond_work_cancel_all() from patch 2/4?
In bond_close(), you can't use cancel_delayed_work_sync() because you can't
unlock RTNL in it. (So, on current implementation, it becomes work cancel is
not ensured on bond_close().)
In sysfs, I think you are right, thanks. So, I will modify the patch as below
(other patches won't be affected).
---
drivers/net/bonding/bond_main.c | 46 ++++++++++++++++++++------------------
drivers/net/bonding/bond_sysfs.c | 34 ++++++++--------------------
drivers/net/bonding/bonding.h | 3 +-
3 files changed, 37 insertions(+), 46 deletions(-)
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -2692,7 +2692,7 @@ out:
void bond_loadbalance_arp_mon(struct work_struct *work)
{
struct bonding *bond = container_of(work, struct bonding,
- arp_work.work);
+ lb_arp_work.work);
struct slave *slave, *oldcurrent;
int do_failover = 0;
int delta_in_ticks;
@@ -2803,7 +2803,7 @@ void bond_loadbalance_arp_mon(struct wor
re_arm:
if (bond->params.arp_interval)
- queue_delayed_work(bond->wq, &bond->arp_work, delta_in_ticks);
+ queue_delayed_work(bond->wq, &bond->lb_arp_work, delta_in_ticks);
out:
read_unlock(&bond->lock);
}
@@ -2826,7 +2826,7 @@ out:
void bond_activebackup_arp_mon(struct work_struct *work)
{
struct bonding *bond = container_of(work, struct bonding,
- arp_work.work);
+ ab_arp_work.work);
struct slave *slave;
int delta_in_ticks;
int i;
@@ -3060,7 +3060,7 @@ void bond_activebackup_arp_mon(struct wo
re_arm:
if (bond->params.arp_interval) {
- queue_delayed_work(bond->wq, &bond->arp_work, delta_in_ticks);
+ queue_delayed_work(bond->wq, &bond->ab_arp_work, delta_in_ticks);
}
out:
read_unlock(&bond->lock);
@@ -3679,30 +3679,23 @@ static int bond_open(struct net_device *
return -1;
}
- INIT_DELAYED_WORK(&bond->alb_work, bond_alb_monitor);
queue_delayed_work(bond->wq, &bond->alb_work, 0);
}
if (bond->params.miimon) { /* link check interval, in milliseconds. */
- INIT_DELAYED_WORK(&bond->mii_work, bond_mii_monitor);
queue_delayed_work(bond->wq, &bond->mii_work, 0);
}
if (bond->params.arp_interval) { /* arp interval, in milliseconds. */
if (bond->params.mode == BOND_MODE_ACTIVEBACKUP)
- INIT_DELAYED_WORK(&bond->arp_work,
- bond_activebackup_arp_mon);
+ queue_delayed_work(bond->wq, &bond->ab_arp_work, 0);
else
- INIT_DELAYED_WORK(&bond->arp_work,
- bond_loadbalance_arp_mon);
-
- queue_delayed_work(bond->wq, &bond->arp_work, 0);
+ queue_delayed_work(bond->wq, &bond->lb_arp_work, 0);
if (bond->params.arp_validate)
bond_register_arp(bond);
}
if (bond->params.mode == BOND_MODE_8023AD) {
- INIT_DELAYED_WORK(&bond->ad_work, bond_3ad_state_machine_handler);
queue_delayed_work(bond->wq, &bond->ad_work, 0);
/* register to receive LACPDUs */
bond_register_lacpdu(bond);
@@ -3736,7 +3729,10 @@ static int bond_close(struct net_device
}
if (bond->params.arp_interval) { /* arp interval, in milliseconds. */
- cancel_delayed_work(&bond->arp_work);
+ if (bond->params.mode == BOND_MODE_ACTIVEBACKUP)
+ cancel_delayed_work(&bond->ab_arp_work);
+ else
+ cancel_delayed_work(&bond->lb_arp_work);
}
switch (bond->params.mode) {
@@ -4416,6 +4412,12 @@ static int bond_init(struct net_device *
if (!bond->wq)
return -ENOMEM;
+ INIT_DELAYED_WORK(&bond->alb_work, bond_alb_monitor);
+ INIT_DELAYED_WORK(&bond->mii_work, bond_mii_monitor);
+ INIT_DELAYED_WORK(&bond->ab_arp_work, bond_activebackup_arp_mon);
+ INIT_DELAYED_WORK(&bond->lb_arp_work, bond_loadbalance_arp_mon);
+ INIT_DELAYED_WORK(&bond->ad_work, bond_3ad_state_machine_handler);
+
/* Initialize pointers */
bond->first_slave = NULL;
bond->curr_active_slave = NULL;
@@ -4498,18 +4500,20 @@ static void bond_work_cancel_all(struct
bond->kill_timers = 1;
write_unlock_bh(&bond->lock);
- if (bond->params.miimon && delayed_work_pending(&bond->mii_work))
+ if (bond->params.miimon)
cancel_delayed_work(&bond->mii_work);
- if (bond->params.arp_interval && delayed_work_pending(&bond->arp_work))
- cancel_delayed_work(&bond->arp_work);
+ if (bond->params.arp_interval) {
+ if (bond->params.mode == BOND_MODE_ACTIVEBACKUP)
+ cancel_delayed_work(&bond->ab_arp_work);
+ else
+ cancel_delayed_work(&bond->lb_arp_work);
+ }
- if (bond->params.mode == BOND_MODE_ALB &&
- delayed_work_pending(&bond->alb_work))
+ if (bond->params.mode == BOND_MODE_ALB)
cancel_delayed_work(&bond->alb_work);
- if (bond->params.mode == BOND_MODE_8023AD &&
- delayed_work_pending(&bond->ad_work))
+ if (bond->params.mode == BOND_MODE_8023AD)
cancel_delayed_work(&bond->ad_work);
}
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -643,10 +643,7 @@ static ssize_t bonding_store_arp_interva
"%s Disabling MII monitoring.\n",
bond->dev->name, bond->dev->name);
bond->params.miimon = 0;
- if (delayed_work_pending(&bond->mii_work)) {
- cancel_delayed_work(&bond->mii_work);
- flush_workqueue(bond->wq);
- }
+ cancel_delayed_work_sync(&bond->mii_work);
}
if (!bond->params.arp_targets[0]) {
printk(KERN_INFO DRV_NAME
@@ -660,16 +657,10 @@ static ssize_t bonding_store_arp_interva
* timer will get fired off when the open function
* is called.
*/
- if (!delayed_work_pending(&bond->arp_work)) {
- if (bond->params.mode == BOND_MODE_ACTIVEBACKUP)
- INIT_DELAYED_WORK(&bond->arp_work,
- bond_activebackup_arp_mon);
- else
- INIT_DELAYED_WORK(&bond->arp_work,
- bond_loadbalance_arp_mon);
-
- queue_delayed_work(bond->wq, &bond->arp_work, 0);
- }
+ if (bond->params.mode == BOND_MODE_ACTIVEBACKUP)
+ queue_delayed_work(bond->wq, &bond->ab_arp_work, 0);
+ else
+ queue_delayed_work(bond->wq, &bond->lb_arp_work, 0);
}
out:
@@ -1022,10 +1013,10 @@ static ssize_t bonding_store_miimon(stru
bond->params.arp_validate =
BOND_ARP_VALIDATE_NONE;
}
- if (delayed_work_pending(&bond->arp_work)) {
- cancel_delayed_work(&bond->arp_work);
- flush_workqueue(bond->wq);
- }
+ if (bond->params.mode == BOND_MODE_ACTIVEBACKUP)
+ cancel_delayed_work_sync(&bond->ab_arp_work);
+ else
+ cancel_delayed_work_sync(&bond->lb_arp_work);
}
if (bond->dev->flags & IFF_UP) {
@@ -1034,12 +1025,7 @@ static ssize_t bonding_store_miimon(stru
* timer will get fired off when the open function
* is called.
*/
- if (!delayed_work_pending(&bond->mii_work)) {
- INIT_DELAYED_WORK(&bond->mii_work,
- bond_mii_monitor);
- queue_delayed_work(bond->wq,
- &bond->mii_work, 0);
- }
+ queue_delayed_work(bond->wq, &bond->mii_work, 0);
}
}
out:
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -206,7 +206,8 @@ struct bonding {
struct packet_type arp_mon_pt;
struct workqueue_struct *wq;
struct delayed_work mii_work;
- struct delayed_work arp_work;
+ struct delayed_work ab_arp_work;
+ struct delayed_work lb_arp_work;
struct delayed_work alb_work;
struct delayed_work ad_work;
};
--
Makito SHIOKAWA
MIRACLE LINUX CORPORATION
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 4/4] bonding: Fix some RTNL taking
2008-01-15 6:36 ` [PATCH 4/4] bonding: Fix some RTNL taking Makito SHIOKAWA
@ 2008-01-16 12:44 ` Jarek Poplawski
2008-01-17 5:30 ` Makito SHIOKAWA
0 siblings, 1 reply; 23+ messages in thread
From: Jarek Poplawski @ 2008-01-16 12:44 UTC (permalink / raw)
To: Makito SHIOKAWA; +Cc: netdev
On 15-01-2008 07:36, Makito SHIOKAWA wrote:
> Fix some RTNL lock taking:
>
> * RTNL (mutex; may sleep) must not be taken under read_lock (spinlock; must be
> atomic). However, RTNL is taken under read_lock in bond_loadbalance_arp_mon()
> and bond_activebackup_arp_mon(). So change code to take RTNL outside of read_lock.
>
> * rtnl_unlock() calls netdev_run_todo() which takes net_todo_run_mutex, and
> rtnl_unlock() is called under read_lock in bond_mii_monitor(). So for the same
> reason as above, change code to call rtnl_unlock() outside of read_lock.
>
> Signed-off-by: Makito SHIOKAWA <mshiokawa@miraclelinux.com>
> ---
> drivers/net/bonding/bond_main.c | 24 ++++++++++--------------
> 1 file changed, 10 insertions(+), 14 deletions(-)
>
> --- a/drivers/net/bonding/bond_main.c
> +++ b/drivers/net/bonding/bond_main.c
> @@ -2372,6 +2372,7 @@ void bond_mii_monitor(struct work_struct
> struct bonding *bond = container_of(work, struct bonding,
> mii_work.work);
> unsigned long delay;
> + int need_unlock = 0;
>
> read_lock(&bond->lock);
> if (bond->kill_timers) {
> @@ -2383,13 +2384,16 @@ void bond_mii_monitor(struct work_struct
> rtnl_lock();
> read_lock(&bond->lock);
> __bond_mii_monitor(bond, 1);
> - rtnl_unlock();
> + need_unlock = 1;
Maybe I'm wrong, but since this read_lock() is given and taken anyway,
it seems this looks a bit better to me (why hold this rtnl longer
than needed?):
read_unlock(&bond->lock);
rtnl_unlock();
read_lock(&bond->lock);
On the other hand, probably 'if (bond->kill_timers)' could be repeated
after this read_lock() retaking.
> }
>
> delay = ((bond->params.miimon * HZ) / 1000) ? : 1;
> - read_unlock(&bond->lock);
> if (bond->params.miimon)
> queue_delayed_work(bond->wq, &bond->mii_work, delay);
If this if () is really necessary here, then this should be better
before "delay = ..." with a block.
> + read_unlock(&bond->lock);
> + /* rtnl_unlock() may sleep, so call it after read_unlock() */
> + if (need_unlock)
> + rtnl_unlock();
> }
Regards,
Jarek P.
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 3/4] bonding: Fix work rearming
2008-01-16 3:19 ` Makito SHIOKAWA
@ 2008-01-16 13:36 ` Jarek Poplawski
2008-01-17 5:30 ` Makito SHIOKAWA
0 siblings, 1 reply; 23+ messages in thread
From: Jarek Poplawski @ 2008-01-16 13:36 UTC (permalink / raw)
To: Makito SHIOKAWA; +Cc: netdev
On Wed, Jan 16, 2008 at 12:19:51PM +0900, Makito SHIOKAWA wrote:
> This patch is supposing a case that bond_mii_monitor() is invoked in
> bond_open(), and after that, 0 is set to miimon via sysfs (see same place
> on other monitors).
> Though message in bonding_store_miimon() says miimon value 1-INT_MAX
> rejected, but it looks like 0 can be accepted and monitor must be stopped
> in that case.
But, since during this change from sysfs cancel_delayed_work_sync()
could be probably used, and it's rather efficient with killing
rearming works, it seems this check could be unnecessary yet.
Jarek P.
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 3/4] bonding: Fix work rearming
2008-01-16 13:36 ` Jarek Poplawski
@ 2008-01-17 5:30 ` Makito SHIOKAWA
2008-01-17 11:18 ` Jarek Poplawski
0 siblings, 1 reply; 23+ messages in thread
From: Makito SHIOKAWA @ 2008-01-17 5:30 UTC (permalink / raw)
To: Jarek Poplawski; +Cc: netdev, Makito SHIOKAWA
> But, since during this change from sysfs cancel_delayed_work_sync()
> could be probably used, and it's rather efficient with killing
> rearming works, it seems this check could be unnecessary yet.
What going to be cancelled in bonding_store_miimon() when setting miimon to 0
is arp monitor, not mii monitor. So, this check will be needed to stop
rearming mii monitor when value 0 is set to miimon.
--
Makito SHIOKAWA
MIRACLE LINUX CORPORATION
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 4/4] bonding: Fix some RTNL taking
2008-01-16 12:44 ` Jarek Poplawski
@ 2008-01-17 5:30 ` Makito SHIOKAWA
2008-01-17 11:46 ` Jarek Poplawski
0 siblings, 1 reply; 23+ messages in thread
From: Makito SHIOKAWA @ 2008-01-17 5:30 UTC (permalink / raw)
To: Jarek Poplawski; +Cc: netdev, Makito SHIOKAWA
> Maybe I'm wrong, but since this read_lock() is given and taken anyway,
> it seems this looks a bit better to me (why hold this rtnl longer
> than needed?):
> read_unlock(&bond->lock);
> rtnl_unlock();
> read_lock(&bond->lock);
Seems better.
> On the other hand, probably 'if (bond->kill_timers)' could be repeated
> after this read_lock() retaking.
Sorry, what do you mean? (A case that bond->kill_timers = 1 is done during
lock retaking, and work being queued only to do 'if (bond->kill_timers)'? If
so, I think that won't differ much.)
> If this if () is really necessary here, then this should be better
> before "delay = ..." with a block.
I agree.
--
Makito SHIOKAWA
MIRACLE LINUX CORPORATION
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 3/4] bonding: Fix work rearming
2008-01-17 5:30 ` Makito SHIOKAWA
@ 2008-01-17 11:18 ` Jarek Poplawski
2008-01-18 13:43 ` Makito SHIOKAWA
0 siblings, 1 reply; 23+ messages in thread
From: Jarek Poplawski @ 2008-01-17 11:18 UTC (permalink / raw)
To: Makito SHIOKAWA; +Cc: netdev
On Thu, Jan 17, 2008 at 02:30:36PM +0900, Makito SHIOKAWA wrote:
>> But, since during this change from sysfs cancel_delayed_work_sync()
>> could be probably used, and it's rather efficient with killing
>> rearming works, it seems this check could be unnecessary yet.
> What going to be cancelled in bonding_store_miimon() when setting miimon to
> 0 is arp monitor, not mii monitor. So, this check will be needed to stop
> rearming mii monitor when value 0 is set to miimon.
Hmm... I'm not sure I understand your point, but it seems both
bonding_store_arp_interval() and bonding_store_miimon() where this
field could be changed, currently use cancel_delayed_work() with
flush_workqueue(), so I presume, there is no rtnl_lock() nor
write_lock(&bond->lock) held, so cancel_delayed_work_sync() could
be used, which doesn't require this additional check.
...Unless you mean that despite miimon value is changed there,
mii_work for some reason can't be cancelled at the same time?
Of course, if there is such a reason for doing this check each time
a work runs instead of controlling where the value changes, then OK!
Regards,
Jarek P.
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 4/4] bonding: Fix some RTNL taking
2008-01-17 5:30 ` Makito SHIOKAWA
@ 2008-01-17 11:46 ` Jarek Poplawski
2008-01-18 9:06 ` Makito SHIOKAWA
0 siblings, 1 reply; 23+ messages in thread
From: Jarek Poplawski @ 2008-01-17 11:46 UTC (permalink / raw)
To: Makito SHIOKAWA; +Cc: netdev
On Thu, Jan 17, 2008 at 02:30:37PM +0900, Makito SHIOKAWA wrote:
>> Maybe I'm wrong, but since this read_lock() is given and taken anyway,
>> it seems this looks a bit better to me (why hold this rtnl longer
>> than needed?):
>> read_unlock(&bond->lock);
>> rtnl_unlock();
>> read_lock(&bond->lock);
> Seems better.
>
>> On the other hand, probably 'if (bond->kill_timers)' could be repeated
>> after this read_lock() retaking.
> Sorry, what do you mean? (A case that bond->kill_timers = 1 is done during
> lock retaking, and work being queued only to do 'if (bond->kill_timers)'?
> If so, I think that won't differ much.)
Probably the difference is not much, but since this all double locking,
unlocking and something between could take a while, and such a check
looks cheaper than re-queueing... But I don't persist in this.
Jarek P.
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 4/4] bonding: Fix some RTNL taking
2008-01-17 11:46 ` Jarek Poplawski
@ 2008-01-18 9:06 ` Makito SHIOKAWA
0 siblings, 0 replies; 23+ messages in thread
From: Makito SHIOKAWA @ 2008-01-18 9:06 UTC (permalink / raw)
To: Jarek Poplawski; +Cc: netdev, Makito SHIOKAWA
> Probably the difference is not much, but since this all double locking,
> unlocking and something between could take a while, and such a check
> looks cheaper than re-queueing... But I don't persist in this.
Looks like this one is settled, thank you for your advice!
--
Makito SHIOKAWA
MIRACLE LINUX CORPORATION
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 3/4] bonding: Fix work rearming
2008-01-17 11:18 ` Jarek Poplawski
@ 2008-01-18 13:43 ` Makito SHIOKAWA
2008-01-18 22:27 ` Jarek Poplawski
0 siblings, 1 reply; 23+ messages in thread
From: Makito SHIOKAWA @ 2008-01-18 13:43 UTC (permalink / raw)
To: Jarek Poplawski; +Cc: netdev, Makito SHIOKAWA
> Hmm... I'm not sure I understand your point, but it seems both
> bonding_store_arp_interval() and bonding_store_miimon() where this
> field could be changed, currently use cancel_delayed_work() with
> flush_workqueue(), so I presume, there is no rtnl_lock() nor
> write_lock(&bond->lock) held, so cancel_delayed_work_sync() could
> be used, which doesn't require this additional check.
I see. I rewrited the patch as below. How about this?
(But, it may be just a matter to change 'if (new_value < 0)' to 'if (new_value
<= 0)' in bonding_store_miimon() and bonding_store_arp_interval()...)
---
drivers/net/bonding/bond_sysfs.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -997,6 +997,8 @@ static ssize_t bonding_store_miimon(stru
": %s: Setting MII monitoring interval to %d.\n",
bond->dev->name, new_value);
bond->params.miimon = new_value;
+ if (bond->params.miimon == 0)
+ cancel_delayed_work_sync(&bond->mii_work);
if(bond->params.updelay)
printk(KERN_INFO DRV_NAME
": %s: Note: Updating updelay (to %d) "
@@ -1026,7 +1028,7 @@ static ssize_t bonding_store_miimon(stru
cancel_delayed_work_sync(&bond->lb_arp_work);
}
- if (bond->dev->flags & IFF_UP) {
+ if (bond->params.miimon && (bond->dev->flags & IFF_UP)) {
/* If the interface is up, we may need to fire off
* the MII timer. If the interface is down, the
* timer will get fired off when the open function
--
Makito SHIOKAWA
MIRACLE LINUX CORPORATION
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 3/4] bonding: Fix work rearming
2008-01-18 13:43 ` Makito SHIOKAWA
@ 2008-01-18 22:27 ` Jarek Poplawski
2008-01-18 22:43 ` Jarek Poplawski
0 siblings, 1 reply; 23+ messages in thread
From: Jarek Poplawski @ 2008-01-18 22:27 UTC (permalink / raw)
To: Makito SHIOKAWA; +Cc: netdev
Makito SHIOKAWA wrote, On 01/18/2008 02:43 PM:
>> Hmm... I'm not sure I understand your point, but it seems both
>> bonding_store_arp_interval() and bonding_store_miimon() where this
>> field could be changed, currently use cancel_delayed_work() with
>> flush_workqueue(), so I presume, there is no rtnl_lock() nor
>> write_lock(&bond->lock) held, so cancel_delayed_work_sync() could
>> be used, which doesn't require this additional check.
> I see. I rewrited the patch as below. How about this?
> (But, it may be just a matter to change 'if (new_value < 0)' to 'if (new_value
> <= 0)' in bonding_store_miimon() and bonding_store_arp_interval()...)
Yes, looks fine to me.
(But new_value = 0 seems needed - just like from module_param()?)
Maybe only a few slight doubts, yet:
- maybe before this cancel IFF_UP test would be useful as well,
- maybe to test if the value has changed at all,
- maybe it's OK, I don't know, but it seems both monitors could be
turned off now.
Thanks,
Jarek P.
>
> ---
> drivers/net/bonding/bond_sysfs.c | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
>
> --- a/drivers/net/bonding/bond_sysfs.c
> +++ b/drivers/net/bonding/bond_sysfs.c
> @@ -997,6 +997,8 @@ static ssize_t bonding_store_miimon(stru
> ": %s: Setting MII monitoring interval to %d.\n",
> bond->dev->name, new_value);
> bond->params.miimon = new_value;
> + if (bond->params.miimon == 0)
> + cancel_delayed_work_sync(&bond->mii_work);
> if(bond->params.updelay)
> printk(KERN_INFO DRV_NAME
> ": %s: Note: Updating updelay (to %d) "
> @@ -1026,7 +1028,7 @@ static ssize_t bonding_store_miimon(stru
> cancel_delayed_work_sync(&bond->lb_arp_work);
> }
>
> - if (bond->dev->flags & IFF_UP) {
> + if (bond->params.miimon && (bond->dev->flags & IFF_UP)) {
> /* If the interface is up, we may need to fire off
> * the MII timer. If the interface is down, the
> * timer will get fired off when the open function
>
>
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 3/4] bonding: Fix work rearming
2008-01-18 22:27 ` Jarek Poplawski
@ 2008-01-18 22:43 ` Jarek Poplawski
2008-01-21 4:04 ` Makito SHIOKAWA
0 siblings, 1 reply; 23+ messages in thread
From: Jarek Poplawski @ 2008-01-18 22:43 UTC (permalink / raw)
To: Jarek Poplawski; +Cc: Makito SHIOKAWA, netdev
Jarek Poplawski wrote, On 01/18/2008 11:27 PM:
> Makito SHIOKAWA wrote, On 01/18/2008 02:43 PM:
...
> @@ -1026,7 +1028,7 @@ static ssize_t bonding_store_miimon(stru
>> cancel_delayed_work_sync(&bond->lb_arp_work);
>> }
>>
>> - if (bond->dev->flags & IFF_UP) {
>> + if (bond->params.miimon && (bond->dev->flags & IFF_UP)) {
...similar change in bonding_store_arp_interval(), I guess?
Jarek P.
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 3/4] bonding: Fix work rearming
2008-01-18 22:43 ` Jarek Poplawski
@ 2008-01-21 4:04 ` Makito SHIOKAWA
2008-01-21 13:33 ` Jarek Poplawski
0 siblings, 1 reply; 23+ messages in thread
From: Makito SHIOKAWA @ 2008-01-21 4:04 UTC (permalink / raw)
To: Jarek Poplawski; +Cc: netdev, Makito SHIOKAWA
> (But new_value = 0 seems needed - just like from module_param()?)
Do you mean to initialize new_value before sscanf()? (There is a check 'if (sscanf(buf, "%d", &new_value) != 1)', so is it necesarry?)
> - maybe to test if the value has changed at all,
Tested.
For now, patch will be like below. Any slight comment for this will be helpful, regards.
Signed-off-by: Makito SHIOKAWA <mshiokawa@miraclelinux.com>
---
drivers/net/bonding/bond_main.c | 11 ++++-------
drivers/net/bonding/bond_sysfs.c | 19 +++++++++++++++++--
2 files changed, 21 insertions(+), 9 deletions(-)
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -2699,7 +2699,7 @@ void bond_loadbalance_arp_mon(struct wor
read_lock(&bond->lock);
- delta_in_ticks = (bond->params.arp_interval * HZ) / 1000;
+ delta_in_ticks = ((bond->params.arp_interval * HZ) / 1000) ? : 1;
if (bond->kill_timers) {
goto out;
@@ -2801,8 +2801,7 @@ void bond_loadbalance_arp_mon(struct wor
}
re_arm:
- if (bond->params.arp_interval)
- queue_delayed_work(bond->wq, &bond->lb_arp_work, delta_in_ticks);
+ queue_delayed_work(bond->wq, &bond->lb_arp_work, delta_in_ticks);
out:
read_unlock(&bond->lock);
}
@@ -2832,7 +2831,7 @@ void bond_activebackup_arp_mon(struct wo
read_lock(&bond->lock);
- delta_in_ticks = (bond->params.arp_interval * HZ) / 1000;
+ delta_in_ticks = ((bond->params.arp_interval * HZ) / 1000) ? : 1;
if (bond->kill_timers) {
goto out;
@@ -3058,9 +3057,7 @@ void bond_activebackup_arp_mon(struct wo
}
re_arm:
- if (bond->params.arp_interval) {
- queue_delayed_work(bond->wq, &bond->ab_arp_work, delta_in_ticks);
- }
+ queue_delayed_work(bond->wq, &bond->ab_arp_work, delta_in_ticks);
out:
read_unlock(&bond->lock);
}
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -644,6 +644,15 @@ static ssize_t bonding_store_arp_interva
": %s: Setting ARP monitoring interval to %d.\n",
bond->dev->name, new_value);
bond->params.arp_interval = new_value;
+ if (bond->params.arp_interval == 0 && (bond->dev->flags & IFF_UP)) {
+ printk(KERN_INFO DRV_NAME
+ ": %s: Disabling ARP monitoring.\n",
+ bond->dev->name);
+ if (bond->params.mode == BOND_MODE_ACTIVEBACKUP)
+ cancel_delayed_work_sync(&bond->ab_arp_work);
+ else
+ cancel_delayed_work_sync(&bond->lb_arp_work);
+ }
if (bond->params.miimon) {
printk(KERN_INFO DRV_NAME
": %s: ARP monitoring cannot be used with MII monitoring. "
@@ -658,7 +667,7 @@ static ssize_t bonding_store_arp_interva
"but no ARP targets have been specified.\n",
bond->dev->name);
}
- if (bond->dev->flags & IFF_UP) {
+ if (bond->params.arp_interval && (bond->dev->flags & IFF_UP)) {
/* If the interface is up, we may need to fire off
* the ARP timer. If the interface is down, the
* timer will get fired off when the open function
@@ -997,6 +1006,12 @@ static ssize_t bonding_store_miimon(stru
": %s: Setting MII monitoring interval to %d.\n",
bond->dev->name, new_value);
bond->params.miimon = new_value;
+ if (bond->params.miimon == 0 && (bond->dev->flags & IFF_UP)) {
+ printk(KERN_INFO DRV_NAME
+ ": %s: Disabling MII monitoring...\n",
+ bond->dev->name);
+ cancel_delayed_work_sync(&bond->mii_work);
+ }
if(bond->params.updelay)
printk(KERN_INFO DRV_NAME
": %s: Note: Updating updelay (to %d) "
@@ -1026,7 +1041,7 @@ static ssize_t bonding_store_miimon(stru
cancel_delayed_work_sync(&bond->lb_arp_work);
}
- if (bond->dev->flags & IFF_UP) {
+ if (bond->params.miimon && (bond->dev->flags & IFF_UP)) {
/* If the interface is up, we may need to fire off
* the MII timer. If the interface is down, the
* timer will get fired off when the open function
--
Makito SHIOKAWA
MIRACLE LINUX CORPORATION
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 3/4] bonding: Fix work rearming
2008-01-21 4:04 ` Makito SHIOKAWA
@ 2008-01-21 13:33 ` Jarek Poplawski
2008-01-22 3:35 ` Makito SHIOKAWA
0 siblings, 1 reply; 23+ messages in thread
From: Jarek Poplawski @ 2008-01-21 13:33 UTC (permalink / raw)
To: Makito SHIOKAWA; +Cc: netdev
On Mon, Jan 21, 2008 at 01:04:06PM +0900, Makito SHIOKAWA wrote:
> > (But new_value = 0 seems needed - just like from module_param()?)
> Do you mean to initialize new_value before sscanf()? (There is a check 'if (sscanf(buf, "%d", &new_value) != 1)', so is it necesarry?)
No: you mentioned about treating new_value == 0 like new_value < 0
with 'if (new_value <= 0)', and I didn't understand this idea...
>
> > - maybe to test if the value has changed at all,
> Tested.
>
> For now, patch will be like below. Any slight comment for this will be helpful, regards.
I think cancelling of delayed works in bond_sysfs is OK now.
Alas I don't understand the reason of this change in bond_main()...
Some comment?
Thanks,
Jarek P.
>
>
> Signed-off-by: Makito SHIOKAWA <mshiokawa@miraclelinux.com>
> ---
> drivers/net/bonding/bond_main.c | 11 ++++-------
> drivers/net/bonding/bond_sysfs.c | 19 +++++++++++++++++--
> 2 files changed, 21 insertions(+), 9 deletions(-)
>
> --- a/drivers/net/bonding/bond_main.c
> +++ b/drivers/net/bonding/bond_main.c
> @@ -2699,7 +2699,7 @@ void bond_loadbalance_arp_mon(struct wor
>
> read_lock(&bond->lock);
>
> - delta_in_ticks = (bond->params.arp_interval * HZ) / 1000;
> + delta_in_ticks = ((bond->params.arp_interval * HZ) / 1000) ? : 1;
>
> if (bond->kill_timers) {
> goto out;
> @@ -2801,8 +2801,7 @@ void bond_loadbalance_arp_mon(struct wor
> }
>
> re_arm:
> - if (bond->params.arp_interval)
> - queue_delayed_work(bond->wq, &bond->lb_arp_work, delta_in_ticks);
> + queue_delayed_work(bond->wq, &bond->lb_arp_work, delta_in_ticks);
> out:
> read_unlock(&bond->lock);
> }
> @@ -2832,7 +2831,7 @@ void bond_activebackup_arp_mon(struct wo
>
> read_lock(&bond->lock);
>
> - delta_in_ticks = (bond->params.arp_interval * HZ) / 1000;
> + delta_in_ticks = ((bond->params.arp_interval * HZ) / 1000) ? : 1;
>
> if (bond->kill_timers) {
> goto out;
> @@ -3058,9 +3057,7 @@ void bond_activebackup_arp_mon(struct wo
> }
>
> re_arm:
> - if (bond->params.arp_interval) {
> - queue_delayed_work(bond->wq, &bond->ab_arp_work, delta_in_ticks);
> - }
> + queue_delayed_work(bond->wq, &bond->ab_arp_work, delta_in_ticks);
> out:
> read_unlock(&bond->lock);
> }
> --- a/drivers/net/bonding/bond_sysfs.c
> +++ b/drivers/net/bonding/bond_sysfs.c
> @@ -644,6 +644,15 @@ static ssize_t bonding_store_arp_interva
> ": %s: Setting ARP monitoring interval to %d.\n",
> bond->dev->name, new_value);
> bond->params.arp_interval = new_value;
> + if (bond->params.arp_interval == 0 && (bond->dev->flags & IFF_UP)) {
> + printk(KERN_INFO DRV_NAME
> + ": %s: Disabling ARP monitoring.\n",
> + bond->dev->name);
> + if (bond->params.mode == BOND_MODE_ACTIVEBACKUP)
> + cancel_delayed_work_sync(&bond->ab_arp_work);
> + else
> + cancel_delayed_work_sync(&bond->lb_arp_work);
> + }
> if (bond->params.miimon) {
> printk(KERN_INFO DRV_NAME
> ": %s: ARP monitoring cannot be used with MII monitoring. "
> @@ -658,7 +667,7 @@ static ssize_t bonding_store_arp_interva
> "but no ARP targets have been specified.\n",
> bond->dev->name);
> }
> - if (bond->dev->flags & IFF_UP) {
> + if (bond->params.arp_interval && (bond->dev->flags & IFF_UP)) {
> /* If the interface is up, we may need to fire off
> * the ARP timer. If the interface is down, the
> * timer will get fired off when the open function
> @@ -997,6 +1006,12 @@ static ssize_t bonding_store_miimon(stru
> ": %s: Setting MII monitoring interval to %d.\n",
> bond->dev->name, new_value);
> bond->params.miimon = new_value;
> + if (bond->params.miimon == 0 && (bond->dev->flags & IFF_UP)) {
> + printk(KERN_INFO DRV_NAME
> + ": %s: Disabling MII monitoring...\n",
> + bond->dev->name);
> + cancel_delayed_work_sync(&bond->mii_work);
> + }
> if(bond->params.updelay)
> printk(KERN_INFO DRV_NAME
> ": %s: Note: Updating updelay (to %d) "
> @@ -1026,7 +1041,7 @@ static ssize_t bonding_store_miimon(stru
> cancel_delayed_work_sync(&bond->lb_arp_work);
> }
>
> - if (bond->dev->flags & IFF_UP) {
> + if (bond->params.miimon && (bond->dev->flags & IFF_UP)) {
> /* If the interface is up, we may need to fire off
> * the MII timer. If the interface is down, the
> * timer will get fired off when the open function
>
>
> --
> Makito SHIOKAWA
> MIRACLE LINUX CORPORATION
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 3/4] bonding: Fix work rearming
2008-01-21 13:33 ` Jarek Poplawski
@ 2008-01-22 3:35 ` Makito SHIOKAWA
0 siblings, 0 replies; 23+ messages in thread
From: Makito SHIOKAWA @ 2008-01-22 3:35 UTC (permalink / raw)
To: Jarek Poplawski; +Cc: netdev, Makito SHIOKAWA
> No: you mentioned about treating new_value == 0 like new_value < 0
> with 'if (new_value <= 0)', and I didn't understand this idea...
I'm sorry to have misunderstood you. I wanted to say that there is a way just
to fix 'if (new_value < 0)' to 'if (new_value <= 0)' and reject miimon == 0,
instead of PATCH 3/4. (Of course, you won't be able to stop mii monitor only
in that case.)
> Alas I don't understand the reason of this change in bond_main()...
> Some comment?
It was unnecessary any more..., thanks.
Signed-off-by: Makito SHIOKAWA <mshiokawa@miraclelinux.com>
---
drivers/net/bonding/bond_main.c | 7 ++-----
drivers/net/bonding/bond_sysfs.c | 19 +++++++++++++++++--
2 files changed, 19 insertions(+), 7 deletions(-)
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -2801,8 +2801,7 @@ void bond_loadbalance_arp_mon(struct wor
}
re_arm:
- if (bond->params.arp_interval)
- queue_delayed_work(bond->wq, &bond->lb_arp_work, delta_in_ticks);
+ queue_delayed_work(bond->wq, &bond->lb_arp_work, delta_in_ticks);
out:
read_unlock(&bond->lock);
}
@@ -3058,9 +3057,7 @@ void bond_activebackup_arp_mon(struct wo
}
re_arm:
- if (bond->params.arp_interval) {
- queue_delayed_work(bond->wq, &bond->ab_arp_work, delta_in_ticks);
- }
+ queue_delayed_work(bond->wq, &bond->ab_arp_work, delta_in_ticks);
out:
read_unlock(&bond->lock);
}
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -644,6 +644,15 @@ static ssize_t bonding_store_arp_interva
": %s: Setting ARP monitoring interval to %d.\n",
bond->dev->name, new_value);
bond->params.arp_interval = new_value;
+ if (bond->params.arp_interval == 0 && (bond->dev->flags & IFF_UP)) {
+ printk(KERN_INFO DRV_NAME
+ ": %s: Disabling ARP monitoring.\n",
+ bond->dev->name);
+ if (bond->params.mode == BOND_MODE_ACTIVEBACKUP)
+ cancel_delayed_work_sync(&bond->ab_arp_work);
+ else
+ cancel_delayed_work_sync(&bond->lb_arp_work);
+ }
if (bond->params.miimon) {
printk(KERN_INFO DRV_NAME
": %s: ARP monitoring cannot be used with MII monitoring. "
@@ -658,7 +667,7 @@ static ssize_t bonding_store_arp_interva
"but no ARP targets have been specified.\n",
bond->dev->name);
}
- if (bond->dev->flags & IFF_UP) {
+ if (bond->params.arp_interval && (bond->dev->flags & IFF_UP)) {
/* If the interface is up, we may need to fire off
* the ARP timer. If the interface is down, the
* timer will get fired off when the open function
@@ -997,6 +1006,12 @@ static ssize_t bonding_store_miimon(stru
": %s: Setting MII monitoring interval to %d.\n",
bond->dev->name, new_value);
bond->params.miimon = new_value;
+ if (bond->params.miimon == 0 && (bond->dev->flags & IFF_UP)) {
+ printk(KERN_INFO DRV_NAME
+ ": %s: Disabling MII monitoring...\n",
+ bond->dev->name);
+ cancel_delayed_work_sync(&bond->mii_work);
+ }
if(bond->params.updelay)
printk(KERN_INFO DRV_NAME
": %s: Note: Updating updelay (to %d) "
@@ -1026,7 +1041,7 @@ static ssize_t bonding_store_miimon(stru
cancel_delayed_work_sync(&bond->lb_arp_work);
}
- if (bond->dev->flags & IFF_UP) {
+ if (bond->params.miimon && (bond->dev->flags & IFF_UP)) {
/* If the interface is up, we may need to fire off
* the MII timer. If the interface is down, the
* timer will get fired off when the open function
--
Makito SHIOKAWA
MIRACLE LINUX CORPORATION
^ permalink raw reply [flat|nested] 23+ messages in thread
end of thread, other threads:[~2008-01-22 3:33 UTC | newest]
Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-01-15 6:36 [PATCH 0/4] bonding: Fix workqueue manipulation and lock taking Makito SHIOKAWA
2008-01-15 6:36 ` [PATCH 1/4] bonding: Fix work initing and cancelling Makito SHIOKAWA
2008-01-15 10:56 ` Jarek Poplawski
2008-01-16 5:17 ` Makito SHIOKAWA
2008-01-15 6:36 ` [PATCH 2/4] bonding: Add destroy_workqueue() to bond device destroying process Makito SHIOKAWA
2008-01-15 6:36 ` [PATCH 3/4] bonding: Fix work rearming Makito SHIOKAWA
2008-01-15 9:05 ` Jarek Poplawski
2008-01-16 3:19 ` Makito SHIOKAWA
2008-01-16 13:36 ` Jarek Poplawski
2008-01-17 5:30 ` Makito SHIOKAWA
2008-01-17 11:18 ` Jarek Poplawski
2008-01-18 13:43 ` Makito SHIOKAWA
2008-01-18 22:27 ` Jarek Poplawski
2008-01-18 22:43 ` Jarek Poplawski
2008-01-21 4:04 ` Makito SHIOKAWA
2008-01-21 13:33 ` Jarek Poplawski
2008-01-22 3:35 ` Makito SHIOKAWA
2008-01-16 3:28 ` Makito SHIOKAWA
2008-01-15 6:36 ` [PATCH 4/4] bonding: Fix some RTNL taking Makito SHIOKAWA
2008-01-16 12:44 ` Jarek Poplawski
2008-01-17 5:30 ` Makito SHIOKAWA
2008-01-17 11:46 ` Jarek Poplawski
2008-01-18 9:06 ` Makito SHIOKAWA
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).