net: dsa: Use delayed work instead of timer+work for polling
Subsystems (3)
PATCH 1/6 net: dsa: Use delayed work instead of timer+work for polling
Simplifies the code and avoids a crash when removing the module:
dsa dsa ethmv2 (unregistering): Link is Down device eth1 left promiscuous mode
Unable to handle kernel paging request at virtual address bacc5cf6 ... (run_timer_softirq) from [<c003e810>] (__do_softirq+0xcc/0x320) (__do_softirq) from [<c003ed40>] (irq_exit+0xac/0x10c) (irq_exit) from [<c007ec20>] (__handle_domain_irq+0x50/0xa8)
Signed-off-by Frode Isaksen <[email protected]>
Signed-off-by Neil Armstrong <[email protected]>
--- include/net/dsa.h | 3 +-- net/dsa/dsa.c | 28 ++++++++-------------------- 2 files changed, 9 insertions(+), 22 deletions(-)
include/net/dsa.h +1 -2
@@ -112,8 +112,7 @@ struct dsa_switch_tree {* Link state polling. */ int link_poll_needed; -struct work_struct link_poll_work; -struct timer_list link_poll_timer; +struct delayed_work link_poll_work;/* * Data for the individual switch chips.
net/dsa/dsa.c +8 -20
@@ -513,7 +513,7 @@ static void dsa_link_poll_work(struct work_struct *ugly)struct dsa_switch_tree *dst;int i; - dst = container_of(ugly, struct dsa_switch_tree, link_poll_work); + dst = container_of(ugly, struct dsa_switch_tree, link_poll_work.work);for (i =0 ; i < dst->pd->nr_chips; i++) {struct dsa_switch *ds = dst->ds[i];
@@ -522,17 +522,9 @@ static void dsa_link_poll_work(struct work_struct *ugly) ds->drv->poll_link (ds); } -mod_timer (&dst->link_poll_timer,round_jiffies (jiffies +HZ )); +schedule_delayed_work (&dst->link_poll_work,round_jiffies_relative (HZ )); } -static void dsa_link_poll_timer (unsigned long _dst) -{ -struct dsa_switch_tree *dst = (void *)_dst; - -schedule_work (&dst->link_poll_work); -} - -/* platform driver init and cleanup *****************************************/ static int dev_is_class (struct device *dev,void *class) {
@@ -880,12 +872,8 @@ static int dsa_setup_dst(struct dsa_switch_tree *dst, struct net_device *dev, dev->dsa_ptr = (void *)dst;if (dst->link_poll_needed) { -INIT_WORK (&dst->link_poll_work, dsa_link_poll_work); -init_timer (&dst->link_poll_timer); - dst->link_poll_timer.data = (unsigned long )dst; - dst->link_poll_timer.function = dsa_link_poll_timer; - dst->link_poll_timer.expires =round_jiffies (jiffies +HZ ); -add_timer (&dst->link_poll_timer); +INIT_DELAYED_WORK (&dst->link_poll_work, dsa_link_poll_work); +schedule_delayed_work (&dst->link_poll_work,round_jiffies_relative (HZ )); }return 0 ;
@@ -954,10 +942,10 @@ static void dsa_remove_dst(struct dsa_switch_tree *dst) {int i; -if (dst->link_poll_needed) -del_timer_sync (&dst->link_poll_timer); - -flush_work (&dst->link_poll_work); +if (dst->link_poll_needed) { +cancel_delayed_work_sync (&dst->link_poll_work); +flush_delayed_work (&dst->link_poll_work); + }for (i =0 ; i < dst->pd->nr_chips; i++) {struct dsa_switch *ds = dst->ds[i];
Signature · 1 line
1.9.1