diff options
| author | Linux Build Service Account <lnxbuild@localhost> | 2017-03-21 05:00:46 -0700 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2017-03-21 05:00:38 -0700 |
| commit | 8da09d99e98c8e79efd3fe208fa79756dd0f8ea3 (patch) | |
| tree | 3def7db15232db03540be5871d30eefa04231cd8 | |
| parent | 124a4c86d1577c19125afbe2bab926a5c64d18f5 (diff) | |
| parent | b6bcf8779bd24d2d884d00afc1d0b1525bade763 (diff) | |
Merge "soc: qcom: glink_smem_native_xprt: Wakeup tx thread in deferred function"
| -rw-r--r-- | drivers/soc/qcom/glink_smem_native_xprt.c | 59 |
1 files changed, 43 insertions, 16 deletions
diff --git a/drivers/soc/qcom/glink_smem_native_xprt.c b/drivers/soc/qcom/glink_smem_native_xprt.c index 14cf10b92122..2dc4208cbc51 100644 --- a/drivers/soc/qcom/glink_smem_native_xprt.c +++ b/drivers/soc/qcom/glink_smem_native_xprt.c @@ -213,6 +213,7 @@ 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; @@ -826,7 +827,6 @@ static void __rx_worker(struct edge_info *einfo, bool atomic_ctx) int i; bool granted; unsigned long flags; - bool trigger_wakeup = false; int rcu_id; uint16_t rcid; uint32_t name_len; @@ -851,22 +851,10 @@ static void __rx_worker(struct edge_info *einfo, bool atomic_ctx) srcu_read_unlock(&einfo->use_ref, rcu_id); return; } - if (!atomic_ctx) { - 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)) { - 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); - } + if ((atomic_ctx) && ((einfo->tx_resume_needed) || + (waitqueue_active(&einfo->tx_blocked_queue)))) /* tx waiting ?*/ + schedule_work(&einfo->wakeup_work); /* * Access to the fifo needs to be synchronized, however only the calls @@ -1174,6 +1162,39 @@ 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. */ @@ -2275,6 +2296,7 @@ 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; @@ -2374,6 +2396,7 @@ 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); @@ -2462,6 +2485,7 @@ 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; @@ -2622,6 +2646,7 @@ 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); @@ -2753,6 +2778,7 @@ 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; @@ -2873,6 +2899,7 @@ 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); |
