[PATCH v2 07/19] staging: brcm80211: remove event handler thread from fullmac
Franky Lin
frankyl at broadcom.com
Fri Sep 23 00:07:44 UTC 2011
Use work queue to defer cfg80211 event handle jobs
Reviewed-by: Roland Vossen <rvossen at broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg at broadcom.com>
Reviewed-by: Arend van Spriel <arend at broadcom.com>
Signed-off-by: Franky Lin <frankyl at broadcom.com>
---
drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c | 85 +++++-----------------
drivers/staging/brcm80211/brcmfmac/wl_cfg80211.h | 3 +-
2 files changed, 21 insertions(+), 67 deletions(-)
diff --git a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c
index 5e86e21..2dd28a2 100644
--- a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c
@@ -3248,69 +3248,30 @@ static void brcmf_put_event(struct brcmf_cfg80211_event_q *e)
kfree(e);
}
-static s32 brcmf_event_handler(void *data)
+static void brcmf_cfg80211_event_handler(struct work_struct *work)
{
struct brcmf_cfg80211_priv *cfg_priv =
- (struct brcmf_cfg80211_priv *)data;
- struct sched_param param = {.sched_priority = MAX_RT_PRIO - 1 };
+ container_of(work, struct brcmf_cfg80211_priv,
+ event_work);
struct brcmf_cfg80211_event_q *e;
- DECLARE_WAITQUEUE(wait, current);
- sched_setscheduler(current, SCHED_FIFO, ¶m);
- allow_signal(SIGTERM);
- add_wait_queue(&cfg_priv->event_waitq, &wait);
- while (1) {
- prepare_to_wait(&cfg_priv->event_waitq, &wait,
- TASK_INTERRUPTIBLE);
-
- schedule();
-
- if (kthread_should_stop())
- break;
-
- e = brcmf_deq_event(cfg_priv);
- if (unlikely(!e)) {
- WL_ERR("event queue empty...\n");
- continue;
- }
-
- do {
- WL_INFO("event type (%d)\n", e->etype);
- if (cfg_priv->el.handler[e->etype])
- cfg_priv->el.handler[e->etype](cfg_priv,
- cfg_to_ndev(cfg_priv),
- &e->emsg, e->edata);
- else
- WL_INFO("Unknown Event (%d): ignoring\n",
- e->etype);
- brcmf_put_event(e);
- } while ((e = brcmf_deq_event(cfg_priv)));
+ e = brcmf_deq_event(cfg_priv);
+ if (unlikely(!e)) {
+ WL_ERR("event queue empty...\n");
+ return;
}
- finish_wait(&cfg_priv->event_waitq, &wait);
- WL_INFO("was terminated\n");
- return 0;
-}
-static s32 brcmf_create_event_handler(struct brcmf_cfg80211_priv *cfg_priv)
-{
- init_waitqueue_head(&cfg_priv->event_waitq);
- cfg_priv->event_tsk = kthread_run(brcmf_event_handler, cfg_priv,
- "wl_event_handler");
- if (IS_ERR(cfg_priv->event_tsk)) {
- cfg_priv->event_tsk = NULL;
- WL_ERR("failed to create event thread\n");
- return -ENOMEM;
- }
- return 0;
-}
+ do {
+ WL_INFO("event type (%d)\n", e->etype);
+ if (cfg_priv->el.handler[e->etype])
+ cfg_priv->el.handler[e->etype](cfg_priv,
+ cfg_to_ndev(cfg_priv),
+ &e->emsg, e->edata);
+ else
+ WL_INFO("Unknown Event (%d): ignoring\n", e->etype);
+ brcmf_put_event(e);
+ } while ((e = brcmf_deq_event(cfg_priv)));
-static void brcmf_destroy_event_handler(struct brcmf_cfg80211_priv *cfg_priv)
-{
- if (cfg_priv->event_tsk) {
- send_sig(SIGTERM, cfg_priv->event_tsk, 1);
- kthread_stop(cfg_priv->event_tsk);
- cfg_priv->event_tsk = NULL;
- }
}
static void brcmf_init_eq(struct brcmf_cfg80211_priv *cfg_priv)
@@ -3352,8 +3313,7 @@ static s32 wl_init_priv(struct brcmf_cfg80211_priv *cfg_priv)
err = brcmf_init_priv_mem(cfg_priv);
if (unlikely(err))
return err;
- if (unlikely(brcmf_create_event_handler(cfg_priv)))
- return -ENOMEM;
+ INIT_WORK(&cfg_priv->event_work, brcmf_cfg80211_event_handler);
brcmf_init_eloop_handler(&cfg_priv->el);
mutex_init(&cfg_priv->usr_sync);
err = brcmf_init_iscan(cfg_priv);
@@ -3368,7 +3328,7 @@ static s32 wl_init_priv(struct brcmf_cfg80211_priv *cfg_priv)
static void wl_deinit_priv(struct brcmf_cfg80211_priv *cfg_priv)
{
- brcmf_destroy_event_handler(cfg_priv);
+ cancel_work_sync(&cfg_priv->event_work);
cfg_priv->dongle_up = false; /* dongle down */
brcmf_flush_eq(cfg_priv);
brcmf_link_down(cfg_priv);
@@ -3438,11 +3398,6 @@ void brcmf_cfg80211_detach(struct brcmf_cfg80211_dev *cfg_dev)
kfree(cfg_dev);
}
-static void brcmf_wakeup_event(struct brcmf_cfg80211_priv *cfg_priv)
-{
- wake_up(&cfg_priv->event_waitq);
-}
-
void
brcmf_cfg80211_event(struct net_device *ndev,
const struct brcmf_event_msg *e, void *data)
@@ -3451,7 +3406,7 @@ brcmf_cfg80211_event(struct net_device *ndev,
struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
if (likely(!brcmf_enq_event(cfg_priv, event_type, e)))
- brcmf_wakeup_event(cfg_priv);
+ schedule_work(&cfg_priv->event_work);
}
static s32 brcmf_dongle_mode(struct net_device *ndev, s32 iftype)
diff --git a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.h b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.h
index d27d4e6..79806c0 100644
--- a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.h
+++ b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.h
@@ -298,8 +298,7 @@ struct brcmf_cfg80211_priv {
struct brcmf_cfg80211_iscan_ctrl *iscan; /* iscan controller */
struct brcmf_cfg80211_connect_info conn_info; /* association info */
struct brcmf_cfg80211_pmk_list *pmk_list; /* wpa2 pmk list */
- struct task_struct *event_tsk; /* task of main event handler thread */
- wait_queue_head_t event_waitq; /* wait queue for main event handling */
+ struct work_struct event_work; /* event handler work struct */
unsigned long status; /* current dongle status */
void *pub;
u32 channel; /* current channel */
--
1.7.1
More information about the devel
mailing list