OSDN Git Service

soc: qcom: glink: Move tx_wakeup_worker to rx tasklet
authorChris Lew <clew@codeaurora.org>
Thu, 11 May 2017 23:54:10 +0000 (16:54 -0700)
committerChris Lew <clew@codeaurora.org>
Wed, 21 Jun 2017 23:33:01 +0000 (16:33 -0700)
Do tx wakeup worker functionality in rx worker tasklet instead
of scheduling the work to be done in worker context to improve
performance.

CRs-Fixed: 2050701
Change-Id: Iba620e7e264805ed02a35603da1fb6c985de7d43
Signed-off-by: Chris Lew <clew@codeaurora.org>
drivers/soc/qcom/glink_smem_native_xprt.c

index 8385987..99caa1c 100644 (file)
@@ -215,7 +215,6 @@ struct edge_info {
        bool tx_blocked_signal_sent;
        struct kthread_work kwork;
        struct kthread_worker kworker;
-       struct work_struct wakeup_work;
        struct task_struct *task;
        struct tasklet_struct tasklet;
        struct srcu_struct use_ref;
@@ -816,6 +815,32 @@ static bool get_rx_fifo(struct edge_info *einfo)
 }
 
 /**
+ * tx_wakeup_worker() - worker function to wakeup tx blocked thread
+ * @work:      kwork associated with the edge to process commands on.
+ */
+static void tx_wakeup_worker(struct edge_info *einfo)
+{
+       bool trigger_wakeup = false;
+       unsigned long flags;
+
+       if (einfo->in_ssr)
+               return;
+       if (einfo->tx_resume_needed && fifo_write_avail(einfo)) {
+               einfo->tx_resume_needed = false;
+               einfo->xprt_if.glink_core_if_ptr->tx_resume(
+                                               &einfo->xprt_if);
+       }
+       spin_lock_irqsave(&einfo->write_lock, flags);
+       if (waitqueue_active(&einfo->tx_blocked_queue)) { /* tx waiting ?*/
+               einfo->tx_blocked_signal_sent = false;
+               trigger_wakeup = true;
+       }
+       spin_unlock_irqrestore(&einfo->write_lock, flags);
+       if (trigger_wakeup)
+               wake_up_all(&einfo->tx_blocked_queue);
+}
+
+/**
  * __rx_worker() - process received commands on a specific edge
  * @einfo:     Edge to process commands on.
  * @atomic_ctx:        Indicates if the caller is in atomic context and requires any
@@ -865,7 +890,7 @@ static void __rx_worker(struct edge_info *einfo, bool atomic_ctx)
 
        if ((atomic_ctx) && ((einfo->tx_resume_needed) ||
                (waitqueue_active(&einfo->tx_blocked_queue)))) /* tx waiting ?*/
-               schedule_work(&einfo->wakeup_work);
+               tx_wakeup_worker(einfo);
 
        /*
         * Access to the fifo needs to be synchronized, however only the calls
@@ -1173,39 +1198,6 @@ static void rx_worker_atomic(unsigned long param)
 }
 
 /**
- * tx_wakeup_worker() - worker function to wakeup tx blocked thread
- * @work:      kwork associated with the edge to process commands on.
- */
-static void tx_wakeup_worker(struct work_struct *work)
-{
-       struct edge_info *einfo;
-       bool trigger_wakeup = false;
-       unsigned long flags;
-       int rcu_id;
-
-       einfo = container_of(work, struct edge_info, wakeup_work);
-       rcu_id = srcu_read_lock(&einfo->use_ref);
-       if (einfo->in_ssr) {
-               srcu_read_unlock(&einfo->use_ref, rcu_id);
-               return;
-       }
-       if (einfo->tx_resume_needed && fifo_write_avail(einfo)) {
-               einfo->tx_resume_needed = false;
-               einfo->xprt_if.glink_core_if_ptr->tx_resume(
-                                               &einfo->xprt_if);
-       }
-       spin_lock_irqsave(&einfo->write_lock, flags);
-       if (waitqueue_active(&einfo->tx_blocked_queue)) { /* tx waiting ?*/
-               einfo->tx_blocked_signal_sent = false;
-               trigger_wakeup = true;
-       }
-       spin_unlock_irqrestore(&einfo->write_lock, flags);
-       if (trigger_wakeup)
-               wake_up_all(&einfo->tx_blocked_queue);
-       srcu_read_unlock(&einfo->use_ref, rcu_id);
-}
-
-/**
  * rx_worker() - worker function to process received commands
  * @work:      kwork associated with the edge to process commands on.
  */
@@ -2355,7 +2347,6 @@ static int glink_smem_native_probe(struct platform_device *pdev)
        init_waitqueue_head(&einfo->tx_blocked_queue);
        init_kthread_work(&einfo->kwork, rx_worker);
        init_kthread_worker(&einfo->kworker);
-       INIT_WORK(&einfo->wakeup_work, tx_wakeup_worker);
        tasklet_init(&einfo->tasklet, rx_worker_atomic, (unsigned long)einfo);
        einfo->read_from_fifo = read_from_fifo;
        einfo->write_to_fifo = write_to_fifo;
@@ -2457,7 +2448,6 @@ request_irq_fail:
 reg_xprt_fail:
 smem_alloc_fail:
        flush_kthread_worker(&einfo->kworker);
-       flush_work(&einfo->wakeup_work);
        kthread_stop(einfo->task);
        einfo->task = NULL;
        tasklet_kill(&einfo->tasklet);
@@ -2546,7 +2536,6 @@ static int glink_rpm_native_probe(struct platform_device *pdev)
        init_waitqueue_head(&einfo->tx_blocked_queue);
        init_kthread_work(&einfo->kwork, rx_worker);
        init_kthread_worker(&einfo->kworker);
-       INIT_WORK(&einfo->wakeup_work, tx_wakeup_worker);
        tasklet_init(&einfo->tasklet, rx_worker_atomic, (unsigned long)einfo);
        einfo->intentless = true;
        einfo->read_from_fifo = memcpy32_fromio;
@@ -2707,7 +2696,6 @@ request_irq_fail:
 reg_xprt_fail:
 toc_init_fail:
        flush_kthread_worker(&einfo->kworker);
-       flush_work(&einfo->wakeup_work);
        kthread_stop(einfo->task);
        einfo->task = NULL;
        tasklet_kill(&einfo->tasklet);
@@ -2839,7 +2827,6 @@ static int glink_mailbox_probe(struct platform_device *pdev)
        init_waitqueue_head(&einfo->tx_blocked_queue);
        init_kthread_work(&einfo->kwork, rx_worker);
        init_kthread_worker(&einfo->kworker);
-       INIT_WORK(&einfo->wakeup_work, tx_wakeup_worker);
        tasklet_init(&einfo->tasklet, rx_worker_atomic, (unsigned long)einfo);
        einfo->read_from_fifo = read_from_fifo;
        einfo->write_to_fifo = write_to_fifo;
@@ -2960,7 +2947,6 @@ request_irq_fail:
 reg_xprt_fail:
 smem_alloc_fail:
        flush_kthread_worker(&einfo->kworker);
-       flush_work(&einfo->wakeup_work);
        kthread_stop(einfo->task);
        einfo->task = NULL;
        tasklet_kill(&einfo->tasklet);