diff options
author | Vinayak Pane <vpane@nvidia.com> | 2014-06-30 00:41:10 -0700 |
---|---|---|
committer | Mandar Padmawar <mpadmawar@nvidia.com> | 2014-07-10 02:05:36 -0700 |
commit | d88d1072164b74617617fa0222bcb72f4deec0fd (patch) | |
tree | e9c487cb99a44ec51e4be6ad23dee1ace699746c | |
parent | 794efb96a6c48900a2f26ac5a739b57844fd69b1 (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.c | 16 |
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); } } |