• Petr Mladek's avatar
    thermal/intel_powerclamp: Convert the kthread to kthread worker API · 8d962ac7
    Petr Mladek authored
    Kthreads are currently implemented as an infinite loop. Each
    has its own variant of checks for terminating, freezing,
    awakening. In many cases it is unclear to say in which state
    it is and sometimes it is done a wrong way.
    
    The plan is to convert kthreads into kthread_worker or workqueues
    API. It allows to split the functionality into separate operations.
    It helps to make a better structure. Also it defines a clean state
    where no locks are taken, IRQs blocked, the kthread might sleep
    or even be safely migrated.
    
    The kthread worker API is useful when we want to have a dedicated
    single thread for the work. It helps to make sure that it is
    available when needed. Also it allows a better control, e.g.
    define a scheduling priority.
    
    This patch converts the intel powerclamp kthreads into the kthread
    worker because they need to have a good control over the assigned
    CPUs.
    
    IMHO, the most natural way is to split one cycle into two works.
    First one does some balancing and let the CPU work normal
    way for some time. The second work checks what the CPU has done
    in the meantime and put it into C-state to reach the required
    idle time ratio. The delay between the two works is achieved
    by the delayed kthread work.
    
    The two works have to share some data that used to be local
    variables of the single kthread function. This is achieved
    by the new per-CPU struct kthread_worker_data. It might look
    as a complication. On the other hand, the long original kthread
    function was not nice either.
    
    The patch tries to avoid extra init and cleanup works. All the
    actions might be done outside the thread. They are moved
    to the functions that create or destroy the worker. Especially,
    I checked that the timers are assigned to the right CPU.
    
    The two works are queuing each other. It makes it a bit tricky to
    break it when we want to stop the worker. We use the global and
    per-worker "clamping" variables to make sure that the re-queuing
    eventually stops. We also cancel the works to make it faster.
    Note that the canceling is not reliable because the handling
    of the two variables and queuing is not synchronized via a lock.
    But it is not a big deal because it is just an optimization.
    The job is stopped faster than before in most cases.
    Signed-off-by: default avatarPetr Mladek <pmladek@suse.com>
    Signed-off-by: default avatarJacob Pan <jacob.jun.pan@linux.intel.com>
    Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
    8d962ac7
intel_powerclamp.c 22.3 KB