summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVinayak Pane <vpane@nvidia.com>2014-06-30 00:41:10 -0700
committerMandar Padmawar <mpadmawar@nvidia.com>2014-07-10 02:05:36 -0700
commitd88d1072164b74617617fa0222bcb72f4deec0fd (patch)
treee9c487cb99a44ec51e4be6ad23dee1ace699746c
parent794efb96a6c48900a2f26ac5a739b57844fd69b1 (diff)
staging: ozwpan: flush workqueue
uevent workqueue needs to be flushed before pd free. destroy workqueue should not have been rescheduled. Don't make work struct NULL again. Bug 200016744 Change-Id: Ief24aad7d787ca3ce6f0c5b4f41656aa50bf2bf4 Signed-off-by: Vinayak Pane <vpane@nvidia.com> Reviewed-on: http://git-master/r/432633 (cherry picked from commit 0011da3e0ed4b8c73992ff630ee8a2972ef8ba33) Reviewed-on: http://git-master/r/435735 GVS: Gerrit_Virtual_Submit Reviewed-by: Anshul Jain (SW) <anshulj@nvidia.com> Tested-by: Anshul Jain (SW) <anshulj@nvidia.com>
-rw-r--r--drivers/staging/ozwpan/ozpd.c16
1 files changed, 11 insertions, 5 deletions
diff --git a/drivers/staging/ozwpan/ozpd.c b/drivers/staging/ozwpan/ozpd.c
index f258d85fcdee..d11eeab90c35 100644
--- a/drivers/staging/ozwpan/ozpd.c
+++ b/drivers/staging/ozwpan/ozpd.c
@@ -39,6 +39,7 @@ static int oz_def_app_start(struct oz_pd *pd, int resume);
static void oz_def_app_stop(struct oz_pd *pd, int pause);
static void oz_def_app_rx(struct oz_pd *pd, struct oz_elt *elt);
static void oz_pd_free(struct work_struct *work);
+static void oz_pd_uevent_workitem(struct work_struct *work);
/*------------------------------------------------------------------------------
* Counts the uncompleted isoc frames submitted to netcard.
*/
@@ -203,8 +204,8 @@ struct oz_pd *oz_pd_alloc(const u8 *mac_addr)
spin_lock_init(&pd->pd_destroy_lock);
pd->pd_destroy_scheduled = false;
- memset(&pd->workitem, 0, sizeof(pd->workitem));
INIT_WORK(&pd->workitem, oz_pd_free);
+ INIT_WORK(&pd->uevent_workitem, oz_pd_uevent_workitem);
}
return pd;
}
@@ -219,6 +220,12 @@ static void oz_pd_free(struct work_struct *work)
oz_trace_msg(M, "Destroying PD:%p\n", pd);
tasklet_kill(&pd->heartbeat_tasklet);
tasklet_kill(&pd->timeout_tasklet);
+
+ /* Finish scheduled uevent work, uevent might be rescheduled by
+ * oz timeout tasklet again
+ */
+ cancel_work_sync(&pd->uevent_workitem);
+
/* Delete any streams.
*/
e = pd->stream_list.next;
@@ -257,6 +264,7 @@ static void oz_pd_free(struct work_struct *work)
oz_trace_msg(M, "%s: dev_put(%p)\n", __func__, pd->net_dev);
dev_put(pd->net_dev);
}
+
kfree(pd);
}
@@ -307,12 +315,10 @@ void oz_pd_notify_uevent(struct oz_pd *pd)
int ret;
oz_pd_get(pd);
- memset(&pd->uevent_workitem, 0, sizeof(pd->uevent_workitem));
- INIT_WORK(&pd->uevent_workitem, oz_pd_uevent_workitem);
- ret = schedule_work(&pd->uevent_workitem);
+ ret = schedule_work(&pd->uevent_workitem);
if (!ret) {
- oz_trace("failed to schedule workitem\n");
+ pr_info("%s: failed to schedule workitem\n", __func__);
oz_pd_put(pd);
}
}