On Fri, Jan 22, 2021 at 08:17:01PM -0500, Joel Fernandes (Google) wrote:
> --- a/kernel/fork.c
> +++ b/kernel/fork.c
> @@ -736,6 +736,7 @@ void __put_task_struct(struct task_struct *tsk)
>       exit_creds(tsk);
>       delayacct_tsk_free(tsk);
>       put_signal_struct(tsk->signal);
> +     sched_tsk_free(tsk);
>  
>       if (!profile_handoff_task(tsk))
>               free_task(tsk);

> +struct sched_core_task_cookie {
> +     refcount_t refcnt;
> +     struct work_struct work; /* to free in WQ context. */;
> +};

> +static void sched_core_put_cookie_work(struct work_struct *ws);
> +
> +/* Caller has to call sched_core_get() if non-zero value is returned. */
> +static unsigned long sched_core_alloc_task_cookie(void)
> +{
> +     struct sched_core_task_cookie *ck =
> +             kmalloc(sizeof(struct sched_core_task_cookie), GFP_KERNEL);
> +
> +     if (!ck)
> +             return 0;
> +     refcount_set(&ck->refcnt, 1);
> +     INIT_WORK(&ck->work, sched_core_put_cookie_work);
> +
> +     return (unsigned long)ck;
> +}

> +static void sched_core_put_task_cookie(unsigned long cookie)
> +{
> +     struct sched_core_task_cookie *ptr =
> +             (struct sched_core_task_cookie *)cookie;
> +
> +     if (refcount_dec_and_test(&ptr->refcnt))
> +             kfree(ptr);
> +}

> +static void sched_core_put_cookie_work(struct work_struct *ws)
> +{
> +     struct sched_core_task_cookie *ck =
> +             container_of(ws, struct sched_core_task_cookie, work);
> +
> +     sched_core_put_task_cookie((unsigned long)ck);
> +     sched_core_put();
> +}

> +void sched_tsk_free(struct task_struct *tsk)
> +{
> +     struct sched_core_task_cookie *ck;
> +
> +     sched_core_put_cookie((struct sched_core_cookie *)tsk->core_cookie);
> +
> +     if (!tsk->core_task_cookie)
> +             return;
> +
> +     ck = (struct sched_core_task_cookie *)tsk->core_task_cookie;
> +     queue_work(system_wq, &ck->work);
> +}

*groan*.. so the purpose of that work is to be able to disable
core-scheduling after the last such task dies.

Maybe add sched_core_put_async() instead?

Reply via email to