Search Linux Wireless

[PATCH 07/20] staging: brcm80211: remove event handler thread from fullmac

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Use work queue to defer cfg80211 event handle jobs

Reviewed-by: Roland Vossen <rvossen@xxxxxxxxxxxx>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@xxxxxxxxxxxx>
Reviewed-by: Arend van Spriel <arend@xxxxxxxxxxxx>
Signed-off-by: Franky Lin <frankyl@xxxxxxxxxxxx>
---
 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, &param);
-	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


--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]
  Powered by Linux