lkml.org 
[lkml]   [2021]   [Feb]   [5]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.19 16/17] kthread: Extract KTHREAD_IS_PER_CPU
    Date
    From: Peter Zijlstra <peterz@infradead.org>

    [ Upstream commit ac687e6e8c26181a33270efd1a2e2241377924b0 ]

    There is a need to distinguish geniune per-cpu kthreads from kthreads
    that happen to have a single CPU affinity.

    Geniune per-cpu kthreads are kthreads that are CPU affine for
    correctness, these will obviously have PF_KTHREAD set, but must also
    have PF_NO_SETAFFINITY set, lest userspace modify their affinity and
    ruins things.

    However, these two things are not sufficient, PF_NO_SETAFFINITY is
    also set on other tasks that have their affinities controlled through
    other means, like for instance workqueues.

    Therefore another bit is needed; it turns out kthread_create_per_cpu()
    already has such a bit: KTHREAD_IS_PER_CPU, which is used to make
    kthread_park()/kthread_unpark() work correctly.

    Expose this flag and remove the implicit setting of it from
    kthread_create_on_cpu(); the io_uring usage of it seems dubious at
    best.

    Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
    Reviewed-by: Valentin Schneider <valentin.schneider@arm.com>
    Tested-by: Valentin Schneider <valentin.schneider@arm.com>
    Link: https://lkml.kernel.org/r/20210121103506.557620262@infradead.org
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    include/linux/kthread.h | 3 +++
    kernel/kthread.c | 27 ++++++++++++++++++++++++++-
    kernel/smpboot.c | 1 +
    3 files changed, 30 insertions(+), 1 deletion(-)

    diff --git a/include/linux/kthread.h b/include/linux/kthread.h
    index c1961761311db..72308c38e06c4 100644
    --- a/include/linux/kthread.h
    +++ b/include/linux/kthread.h
    @@ -32,6 +32,9 @@ struct task_struct *kthread_create_on_cpu(int (*threadfn)(void *data),
    unsigned int cpu,
    const char *namefmt);

    +void kthread_set_per_cpu(struct task_struct *k, int cpu);
    +bool kthread_is_per_cpu(struct task_struct *k);
    +
    /**
    * kthread_run - create and wake a thread.
    * @threadfn: the function to run until signal_pending(current).
    diff --git a/kernel/kthread.c b/kernel/kthread.c
    index 2eed853ab9cc5..81abfac351272 100644
    --- a/kernel/kthread.c
    +++ b/kernel/kthread.c
    @@ -460,11 +460,36 @@ struct task_struct *kthread_create_on_cpu(int (*threadfn)(void *data),
    return p;
    kthread_bind(p, cpu);
    /* CPU hotplug need to bind once again when unparking the thread. */
    - set_bit(KTHREAD_IS_PER_CPU, &to_kthread(p)->flags);
    to_kthread(p)->cpu = cpu;
    return p;
    }

    +void kthread_set_per_cpu(struct task_struct *k, int cpu)
    +{
    + struct kthread *kthread = to_kthread(k);
    + if (!kthread)
    + return;
    +
    + WARN_ON_ONCE(!(k->flags & PF_NO_SETAFFINITY));
    +
    + if (cpu < 0) {
    + clear_bit(KTHREAD_IS_PER_CPU, &kthread->flags);
    + return;
    + }
    +
    + kthread->cpu = cpu;
    + set_bit(KTHREAD_IS_PER_CPU, &kthread->flags);
    +}
    +
    +bool kthread_is_per_cpu(struct task_struct *k)
    +{
    + struct kthread *kthread = to_kthread(k);
    + if (!kthread)
    + return false;
    +
    + return test_bit(KTHREAD_IS_PER_CPU, &kthread->flags);
    +}
    +
    /**
    * kthread_unpark - unpark a thread created by kthread_create().
    * @k: thread created by kthread_create().
    diff --git a/kernel/smpboot.c b/kernel/smpboot.c
    index c230c2dd48e19..84c16654d8598 100644
    --- a/kernel/smpboot.c
    +++ b/kernel/smpboot.c
    @@ -187,6 +187,7 @@ __smpboot_create_thread(struct smp_hotplug_thread *ht, unsigned int cpu)
    kfree(td);
    return PTR_ERR(tsk);
    }
    + kthread_set_per_cpu(tsk, cpu);
    /*
    * Park the thread so that it could start right on the CPU
    * when it is available.
    --
    2.27.0


    \
     
     \ /
      Last update: 2021-02-05 23:22    [W:8.376 / U:0.048 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site