[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Minios-devel] [UNIKRAFT PATCH v2 5/6] lib/uksched: create and delete thread-local storage area



This patch is fine.

Reviewed-by: Costin Lupu <costin.lupu@xxxxxxxxx>

On 5/24/19 3:11 PM, Florian Schmidt wrote:
> Most of the actual TLS setup is architecture-specific, so sched.c and
> thread.c call functions from a header file provided in arch/.
> 
> Signed-off-by: Florian Schmidt <florian.schmidt@xxxxxxxxx>
> ---
>  lib/uksched/include/uk/sched.h  |  3 +++
>  lib/uksched/include/uk/thread.h |  3 ++-
>  lib/uksched/sched.c             | 35 ++++++++++++++++++++++++++++++---
>  lib/uksched/thread.c            |  8 +++++---
>  4 files changed, 42 insertions(+), 7 deletions(-)
> 
> diff --git a/lib/uksched/include/uk/sched.h b/lib/uksched/include/uk/sched.h
> index f9dc16d0..5674cc96 100644
> --- a/lib/uksched/include/uk/sched.h
> +++ b/lib/uksched/include/uk/sched.h
> @@ -50,6 +50,9 @@ struct uk_sched;
>  
>  struct uk_sched *uk_sched_default_init(struct uk_alloc *a);
>  
> +extern char _tls_start[], _etdata[], _tls_end[];
> +#define have_tls_area() (_tls_end - _tls_start)
> +
>  extern struct uk_sched *uk_sched_head;
>  int uk_sched_register(struct uk_sched *s);
>  struct uk_sched *uk_sched_get_default(void);
> diff --git a/lib/uksched/include/uk/thread.h b/lib/uksched/include/uk/thread.h
> index 71e39225..8cb3d6b6 100644
> --- a/lib/uksched/include/uk/thread.h
> +++ b/lib/uksched/include/uk/thread.h
> @@ -50,6 +50,7 @@ struct uk_sched;
>  struct uk_thread {
>       const char *name;
>       void *stack;
> +     void *tls;
>       void *ctx;
>       UK_TAILQ_ENTRY(struct uk_thread) thread_list;
>       uint32_t flags;
> @@ -106,7 +107,7 @@ struct uk_thread *uk_thread_current(void)
>  
>  int uk_thread_init(struct uk_thread *thread,
>               struct ukplat_ctx_callbacks *cbs, struct uk_alloc *allocator,
> -             const char *name, void *stack,
> +             const char *name, void *stack, void *tls,
>               void (*function)(void *), void *arg);
>  void uk_thread_fini(struct uk_thread *thread,
>               struct uk_alloc *allocator);
> diff --git a/lib/uksched/sched.c b/lib/uksched/sched.c
> index e0416736..a2505479 100644
> --- a/lib/uksched/sched.c
> +++ b/lib/uksched/sched.c
> @@ -33,10 +33,12 @@
>   */
>  
>  #include <stdlib.h>
> +#include <string.h>
>  #include <uk/plat/config.h>
>  #include <uk/plat/thread.h>
>  #include <uk/alloc.h>
>  #include <uk/sched.h>
> +#include <uk/arch/tls.h>
>  #if CONFIG_LIBUKSCHEDCOOP
>  #include <uk/schedcoop.h>
>  #endif
> @@ -148,27 +150,45 @@ static void *create_stack(struct uk_alloc *allocator)
>       return stack;
>  }
>  
> +static void *uk_thread_tls_create(struct uk_alloc *allocator)
> +{
> +     void *tls;
> +
> +     if (uk_posix_memalign(allocator, &tls, ukarch_tls_area_align(),
> +                             ukarch_tls_area_size()))
> +             return NULL;
> +     ukarch_tls_area_copy(tls);
> +     return tls;
> +}
> +
>  void uk_sched_idle_init(struct uk_sched *sched,
>               void *stack, void (*function)(void *))
>  {
>       struct uk_thread *idle;
>       int rc;
> +     void *tls = NULL;
>  
>       UK_ASSERT(sched != NULL);
>  
>       if (stack == NULL)
>               stack = create_stack(sched->allocator);
>       UK_ASSERT(stack != NULL);
> +     if (have_tls_area() && !(tls = uk_thread_tls_create(sched->allocator)))
> +             goto out_crash;
>  
>       idle = &sched->idle;
>  
>       rc = uk_thread_init(idle,
>                       &sched->plat_ctx_cbs, sched->allocator,
> -                     "Idle", stack, function, NULL);
> +                     "Idle", stack, tls, function, NULL);
>       if (rc)
> -             UK_CRASH("Error initializing idle thread.");
> +             goto out_crash;
>  
>       idle->sched = sched;
> +     return;
> +
> +out_crash:
> +     UK_CRASH("Error initializing the idle thread.");
>  }
>  
>  struct uk_thread *uk_sched_thread_create(struct uk_sched *sched,
> @@ -178,6 +198,7 @@ struct uk_thread *uk_sched_thread_create(struct uk_sched 
> *sched,
>       struct uk_thread *thread = NULL;
>       void *stack = NULL;
>       int rc;
> +     void *tls = NULL;
>  
>       thread = uk_malloc(sched->allocator, sizeof(struct uk_thread));
>       if (thread == NULL) {
> @@ -191,10 +212,12 @@ struct uk_thread *uk_sched_thread_create(struct 
> uk_sched *sched,
>       stack = create_stack(sched->allocator);
>       if (stack == NULL)
>               goto err;
> +     if (have_tls_area() && !(tls = uk_thread_tls_create(sched->allocator)))
> +             goto err;
>  
>       rc = uk_thread_init(thread,
>                       &sched->plat_ctx_cbs, sched->allocator,
> -                     name, stack, function, arg);
> +                     name, stack, tls, function, arg);
>       if (rc)
>               goto err;
>  
> @@ -207,6 +230,8 @@ struct uk_thread *uk_sched_thread_create(struct uk_sched 
> *sched,
>  err_add:
>       uk_thread_fini(thread, sched->allocator);
>  err:
> +     if (tls)
> +             uk_free(sched->allocator, tls);
>       if (stack)
>               uk_free(sched->allocator, stack);
>       if (thread)
> @@ -219,11 +244,15 @@ void uk_sched_thread_destroy(struct uk_sched *sched, 
> struct uk_thread *thread)
>  {
>       UK_ASSERT(sched != NULL);
>       UK_ASSERT(thread != NULL);
> +     UK_ASSERT(thread->stack != NULL);
> +     UK_ASSERT(!have_tls_area() || thread->tls != NULL);
>       UK_ASSERT(is_exited(thread));
>  
>       UK_TAILQ_REMOVE(&sched->exited_threads, thread, thread_list);
>       uk_thread_fini(thread, sched->allocator);
>       uk_pfree(sched->allocator, thread->stack, STACK_SIZE_PAGE_ORDER);
> +     if (thread->tls)
> +             uk_free(sched->allocator, thread->tls);
>       uk_free(sched->allocator, thread);
>  }
>  
> diff --git a/lib/uksched/thread.c b/lib/uksched/thread.c
> index 7400baee..7d7ee016 100644
> --- a/lib/uksched/thread.c
> +++ b/lib/uksched/thread.c
> @@ -88,13 +88,14 @@ struct _reent *__getreent(void)
>  
>  int uk_thread_init(struct uk_thread *thread,
>               struct ukplat_ctx_callbacks *cbs, struct uk_alloc *allocator,
> -             const char *name, void *stack,
> +             const char *name, void *stack, void *tls,
>               void (*function)(void *), void *arg)
>  {
>       unsigned long sp;
>  
>       UK_ASSERT(thread != NULL);
>       UK_ASSERT(stack != NULL);
> +     UK_ASSERT(!have_tls_area() || tls != NULL);
>  
>       /* Save pointer to the thread on the stack to get current thread */
>       *((unsigned long *) stack) = (unsigned long) thread;
> @@ -108,6 +109,7 @@ int uk_thread_init(struct uk_thread *thread,
>  
>       thread->name = name;
>       thread->stack = stack;
> +     thread->tls = tls;
>  
>       /* Not runnable, not exited, not sleeping */
>       thread->flags = 0;
> @@ -121,8 +123,8 @@ int uk_thread_init(struct uk_thread *thread,
>       reent_init(&thread->reent);
>  #endif
>  
> -     uk_pr_info("Thread \"%s\": pointer: %p, stack: %p\n",
> -                name, thread, thread->stack);
> +     uk_pr_info("Thread \"%s\": pointer: %p, stack: %p, tls: %p\n",
> +                name, thread, thread->stack, thread->tls);
>  
>       return 0;
>  }
> 

_______________________________________________
Minios-devel mailing list
Minios-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/minios-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.