psi: get poll_work to run when calling poll syscall next time
[sfrench/cifs-2.6.git] / kernel / sched / psi.c
index 7acc632c3b82bebceeff2cfdc06eb652096f912b..6e52b67b420e7a3312f463f8d3bb6baad6576041 100644 (file)
@@ -1051,7 +1051,7 @@ struct psi_trigger *psi_trigger_create(struct psi_group *group,
 
        if (!rcu_access_pointer(group->poll_kworker)) {
                struct sched_param param = {
-                       .sched_priority = MAX_RT_PRIO - 1,
+                       .sched_priority = 1,
                };
                struct kthread_worker *kworker;
 
@@ -1061,7 +1061,7 @@ struct psi_trigger *psi_trigger_create(struct psi_group *group,
                        mutex_unlock(&group->trigger_lock);
                        return ERR_CAST(kworker);
                }
-               sched_setscheduler(kworker->task, SCHED_FIFO, &param);
+               sched_setscheduler_nocheck(kworker->task, SCHED_FIFO, &param);
                kthread_init_delayed_work(&group->poll_work,
                                psi_poll_work);
                rcu_assign_pointer(group->poll_kworker, kworker);
@@ -1131,7 +1131,15 @@ static void psi_trigger_destroy(struct kref *ref)
         * deadlock while waiting for psi_poll_work to acquire trigger_lock
         */
        if (kworker_to_destroy) {
+               /*
+                * After the RCU grace period has expired, the worker
+                * can no longer be found through group->poll_kworker.
+                * But it might have been already scheduled before
+                * that - deschedule it cleanly before destroying it.
+                */
                kthread_cancel_delayed_work_sync(&group->poll_work);
+               atomic_set(&group->poll_scheduled, 0);
+
                kthread_destroy_worker(kworker_to_destroy);
        }
        kfree(t);