Skip to content

Commit

Permalink
msm-tsens: Reschedule work instead of causing uninterruptible sleep
Browse files Browse the repository at this point in the history
The tsens_poll work causes uninterruptible sleep on the UI
thread and thus blocks other tasks from running due to the
msleep call.

To avoid this condition, we introduce a variable to hold
the staging state of the critical polling and reschedule the
work itself to be executed again after the same
duration as the msleep.

Additionally we switch the currently unused wq to
a singlethreaded wq and queue the tsens work onto
that wq.

Change-Id: I0bf48837310decd035d35ac78aa7d51614032b36
Signed-off-by: Alex Naidis <alex.naidis@linux.com>
Signed-off-by: Ícaro Hoff <icarohoff@gmail.com>
  • Loading branch information
TheCrazyLex authored and GalaticStryder committed Sep 14, 2018
1 parent caec4c6 commit d671bf7
Showing 1 changed file with 22 additions and 9 deletions.
31 changes: 22 additions & 9 deletions drivers/thermal/msm-tsens.c
Original file line number Diff line number Diff line change
Expand Up @@ -867,6 +867,7 @@ struct tsens_tm_device {
u64 qtimer_val_last_detection_interrupt;
u64 qtimer_val_last_polling_check;
bool tsens_critical_poll;
bool tsens_critical_poll_state;
struct tsens_tm_device_sensor sensor[0];
};

Expand Down Expand Up @@ -2010,7 +2011,7 @@ static void tsens_poll(struct work_struct *work)
unsigned int debug_id = 0, cntrl_id = 0;
uint32_t r1, r2, r3, r4, offset = 0, idx = 0;
unsigned long temp, flags;
unsigned int status, int_mask, int_mask_val;
unsigned int status, int_mask, int_mask_val, resched_ms;
void __iomem *srot_addr;
void __iomem *controller_id_addr;
void __iomem *debug_id_addr;
Expand All @@ -2034,6 +2035,10 @@ static void tsens_poll(struct work_struct *work)
/* Sensor 0 on either of the controllers */
mask = 0;

if (tmdev->tsens_critical_poll_state) {
goto critical_poll;
}

reinit_completion(&tmdev->tsens_rslt_completion);

temp &= TSENS_TM_SN_CRITICAL_THRESHOLD_MASK;
Expand Down Expand Up @@ -2069,8 +2074,12 @@ static void tsens_poll(struct work_struct *work)
}
spin_unlock_irqrestore(&tmdev->tsens_crit_lock, flags);

if (tmdev->tsens_critical_poll) {
msleep(TSENS_DEBUG_POLL_MS);
critical_poll:
if (tmdev->tsens_critical_poll && !tmdev->tsens_critical_poll_state) {
tmdev->tsens_critical_poll_state = true;
goto re_schedule;
} else if (tmdev->tsens_critical_poll) {
tmdev->tsens_critical_poll_state = false;
sensor_status_addr = TSENS_TM_SN_STATUS(tmdev->tsens_addr);

spin_lock_irqsave(&tmdev->tsens_crit_lock, flags);
Expand Down Expand Up @@ -2230,9 +2239,11 @@ static void tsens_poll(struct work_struct *work)
}

re_schedule:

schedule_delayed_work(&tmdev->tsens_critical_poll_test,
msecs_to_jiffies(tsens_sec_to_msec_value));
resched_ms = tmdev->tsens_critical_poll_state
? TSENS_DEBUG_POLL_MS : tsens_sec_to_msec_value;
queue_delayed_work(tmdev->tsens_critical_wq,
&tmdev->tsens_critical_poll_test,
msecs_to_jiffies(resched_ms));
}

int tsens_mtc_reset_history_counter(unsigned int zone)
Expand Down Expand Up @@ -5744,8 +5755,8 @@ static int tsens_tm_probe(struct platform_device *pdev)

tmdev->pdev = pdev;

tmdev->tsens_critical_wq = alloc_workqueue("tsens_critical_wq",
WQ_HIGHPRI, 0);
tmdev->tsens_critical_wq = create_singlethread_workqueue("tsens_critical_wq");

if (!tmdev->tsens_critical_wq) {
rc = -ENOMEM;
goto fail;
Expand All @@ -5770,6 +5781,7 @@ static int tsens_tm_probe(struct platform_device *pdev)
spin_lock_init(&tmdev->tsens_upp_low_lock);
spin_lock_init(&tmdev->tsens_debug_lock);

tmdev->tsens_critical_poll_state = false;
tmdev->is_ready = true;

list_add_tail(&tmdev->list, &tsens_device_list);
Expand Down Expand Up @@ -5938,7 +5950,8 @@ static int tsens_thermal_zone_register(struct tsens_tm_device *tmdev)
if (tsens_poll_check) {
INIT_DEFERRABLE_WORK(&tmdev->tsens_critical_poll_test,
tsens_poll);
schedule_delayed_work(&tmdev->tsens_critical_poll_test,
queue_delayed_work(tmdev->tsens_critical_wq,
&tmdev->tsens_critical_poll_test,
msecs_to_jiffies(tsens_sec_to_msec_value));
init_completion(&tmdev->tsens_rslt_completion);
tmdev->tsens_critical_poll = true;
Expand Down

0 comments on commit d671bf7

Please sign in to comment.