Skip to content

Commit 9ca0659

Browse files
skuenzerunikraft-bot
authored andcommitted
include/: No dependency to lib/ukalloc for thread contexts
Changes the platform API in a way so that there is no dependency to `ukalloc` for context creation. An API function is added to query the allocation size for a thread context. Another API function is added to call the platform-specific thread context initialization. Signed-off-by: Simon Kuenzer <[email protected]> Reviewed-by: Daniel Dinca <[email protected]> Tested-by: Unikraft CI <[email protected]> GitHub-Pull-Request: unikraft#138
1 parent 56943ad commit 9ca0659

File tree

6 files changed

+65
-50
lines changed

6 files changed

+65
-50
lines changed

include/uk/plat/thread.h

+19-13
Original file line numberDiff line numberDiff line change
@@ -46,19 +46,19 @@ enum ukplat_ctx_type {
4646
ukplat_ctx_sw,
4747
};
4848

49-
struct uk_alloc;
50-
51-
typedef void *(*ukplat_ctx_create_func_t)
52-
(struct uk_alloc *allocator, unsigned long sp,
53-
unsigned long tlsp);
49+
typedef __sz (*ukplat_ctx_size_func_t)(void);
50+
typedef void (*ukplat_ctx_init_func_t)
51+
(void *ctx, unsigned long sp, unsigned long tlsp);
5452
typedef void (*ukplat_ctx_start_func_t)
5553
(void *ctx);
5654
typedef void (*ukplat_ctx_switch_func_t)
5755
(void *prevctx, void *nextctx);
5856

5957
struct ukplat_ctx_callbacks {
60-
/* callback for creating thread context */
61-
ukplat_ctx_create_func_t create_cb;
58+
/* callback for returning the needed size for a thread context */
59+
ukplat_ctx_size_func_t size_cb;
60+
/* callback for initializing a new thread context */
61+
ukplat_ctx_init_func_t init_cb;
6262
/* callback for starting thread context */
6363
ukplat_ctx_start_func_t start_cb __noreturn;
6464
/* callback for switching contexts */
@@ -70,17 +70,23 @@ int ukplat_ctx_callbacks_init(struct ukplat_ctx_callbacks *ctx_cbs,
7070

7171

7272
static inline
73-
void *ukplat_thread_ctx_create(struct ukplat_ctx_callbacks *cbs,
74-
struct uk_alloc *allocator, unsigned long sp,
75-
unsigned long tlsp)
73+
__sz ukplat_thread_ctx_size(struct ukplat_ctx_callbacks *cbs)
7674
{
7775
UK_ASSERT(cbs != __NULL);
78-
UK_ASSERT(allocator != __NULL);
7976

80-
return cbs->create_cb(allocator, sp, tlsp);
77+
return cbs->size_cb();
8178
}
8279

83-
void ukplat_thread_ctx_destroy(struct uk_alloc *allocator, void *ctx);
80+
static inline
81+
void ukplat_thread_ctx_init(struct ukplat_ctx_callbacks *cbs,
82+
void *ctx,
83+
unsigned long sp, unsigned long tlsp)
84+
{
85+
UK_ASSERT(cbs != __NULL);
86+
UK_ASSERT(ctx != __NULL);
87+
88+
return cbs->init_cb(ctx, sp, tlsp);
89+
}
8490

8591
static inline
8692
void ukplat_thread_ctx_start(struct ukplat_ctx_callbacks *cbs,

lib/uksched/include/uk/thread.h

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#ifdef CONFIG_LIBNEWLIBC
3434
#include <sys/reent.h>
3535
#endif
36+
#include <uk/alloc.h>
3637
#include <uk/arch/lcpu.h>
3738
#include <uk/arch/time.h>
3839
#include <uk/plat/thread.h>

lib/uksched/thread.c

+20-6
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ int uk_thread_init(struct uk_thread *thread,
9494
void (*function)(void *), void *arg)
9595
{
9696
unsigned long sp;
97+
void *ctx;
98+
int ret = 0;
9799

98100
UK_ASSERT(thread != NULL);
99101
UK_ASSERT(stack != NULL);
@@ -104,12 +106,15 @@ int uk_thread_init(struct uk_thread *thread,
104106

105107
init_sp(&sp, stack, function, arg);
106108

107-
/* Call platform specific setup. */
108-
thread->ctx = ukplat_thread_ctx_create(cbs, allocator, sp,
109-
(uintptr_t)ukarch_tls_pointer(tls));
110-
if (thread->ctx == NULL)
111-
return -1;
109+
/* Allocate thread context */
110+
ctx = uk_zalloc(allocator, ukplat_thread_ctx_size(cbs));
111+
if (!ctx) {
112+
ret = -1;
113+
goto err_out;
114+
}
112115

116+
memset(thread, 0, sizeof(*thread));
117+
thread->ctx = ctx;
113118
thread->name = name;
114119
thread->stack = stack;
115120
thread->tls = tls;
@@ -129,10 +134,17 @@ int uk_thread_init(struct uk_thread *thread,
129134
uk_thread_sig_init(&thread->signals_container);
130135
#endif
131136

137+
/* Platform specific context initialization */
138+
ukplat_thread_ctx_init(cbs, thread->ctx, sp,
139+
(uintptr_t) ukarch_tls_pointer(tls));
140+
132141
uk_pr_info("Thread \"%s\": pointer: %p, stack: %p, tls: %p\n",
133142
name, thread, thread->stack, thread->tls);
134143

135144
return 0;
145+
146+
err_out:
147+
return ret;
136148
}
137149

138150
void uk_thread_fini(struct uk_thread *thread, struct uk_alloc *allocator)
@@ -141,7 +153,9 @@ void uk_thread_fini(struct uk_thread *thread, struct uk_alloc *allocator)
141153
#if CONFIG_LIBUKSIGNAL
142154
uk_thread_sig_uninit(&thread->signals_container);
143155
#endif
144-
ukplat_thread_ctx_destroy(allocator, thread->ctx);
156+
157+
uk_free(allocator, thread->ctx);
158+
thread->ctx = NULL;
145159
}
146160

147161
static void uk_thread_block_until(struct uk_thread *thread, __snsec until)

plat/common/include/uk/plat/common/sw_ctx.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ struct sw_ctx {
4343
uintptr_t extregs; /* Pointer to an area to which extended
4444
* registers are saved on context switch.
4545
*/
46+
uint8_t _extregs[]; /* Reserved memory area for extended
47+
* registers state
48+
*/
4649
};
4750

4851
void sw_ctx_callbacks_init(struct ukplat_ctx_callbacks *ctx_cbs);
@@ -51,8 +54,6 @@ void sw_ctx_callbacks_init(struct ukplat_ctx_callbacks *ctx_cbs);
5154
#define OFFSETOF_SW_CTX_SP 0
5255
#define OFFSETOF_SW_CTX_IP 8
5356

54-
#define SIZEOF_SW_CTX 8
55-
5657
/* TODO This should be better defined in the thread header */
5758
#define OFFSETOF_UKTHREAD_SW_CTX 16
5859

plat/common/include/x86/cpu.h

+5-10
Original file line numberDiff line numberDiff line change
@@ -110,22 +110,17 @@ static inline void restore_extregs(struct sw_ctx *ctx)
110110
}
111111
}
112112

113-
static inline struct sw_ctx *arch_alloc_sw_ctx(struct uk_alloc *allocator)
113+
static inline __sz arch_extregs_size(void)
114114
{
115-
struct sw_ctx *ctx;
116-
size_t sz;
115+
/* Make sure that _init_cpufeatures() was called before */
116+
UK_ASSERT(x86_cpu_features.extregs_size > 0);
117117

118-
sz = ALIGN_UP(sizeof(struct sw_ctx), x86_cpu_features.extregs_align)
119-
+ x86_cpu_features.extregs_size;
120-
ctx = uk_malloc(allocator, sz);
121-
uk_pr_debug("Allocating %lu bytes for sw ctx at %p\n", sz, ctx);
122-
123-
return ctx;
118+
return x86_cpu_features.extregs_align + x86_cpu_features.extregs_size;
124119
}
125120

126121
static inline void arch_init_extregs(struct sw_ctx *ctx)
127122
{
128-
ctx->extregs = ALIGN_UP(((uintptr_t)ctx + sizeof(struct sw_ctx)),
123+
ctx->extregs = ALIGN_UP((uintptr_t)ctx->_extregs,
129124
x86_cpu_features.extregs_align);
130125
// Initialize extregs area: zero out, then save a valid layout to it.
131126
memset((void *)ctx->extregs, 0, x86_cpu_features.extregs_size);

plat/common/sw_ctx.c

+17-19
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@
3838
#include <uk/plat/common/tls.h>
3939
#include <uk/plat/common/cpu.h>
4040

41-
static void *sw_ctx_create(struct uk_alloc *allocator, unsigned long sp,
42-
unsigned long tlsp);
41+
static size_t sw_ctx_size(void);
42+
static void sw_ctx_init(void *ctx, unsigned long sp, unsigned long tlsp);
4343
static void sw_ctx_start(void *ctx) __noreturn;
4444
static void sw_ctx_switch(void *prevctx, void *nextctx);
4545

@@ -49,27 +49,24 @@ static void sw_ctx_switch(void *prevctx, void *nextctx);
4949
*/
5050
extern void asm_thread_starter(void);
5151

52-
static void *sw_ctx_create(struct uk_alloc *allocator, unsigned long sp,
53-
unsigned long tlsp)
52+
static size_t sw_ctx_size(void)
5453
{
55-
struct sw_ctx *ctx;
56-
57-
UK_ASSERT(allocator != NULL);
54+
return sizeof(struct ukplat_ctx) + arch_extregs_size();
55+
}
5856

59-
ctx = arch_alloc_sw_ctx(allocator);
60-
if (ctx == NULL) {
61-
uk_pr_warn("Error allocating software context.");
62-
return NULL;
63-
}
57+
static void sw_ctx_init(void *ctx,
58+
unsigned long sp, unsigned long tlsp)
59+
{
60+
struct sw_ctx *sw_ctx = ctx;
6461

65-
ctx->sp = sp;
66-
ctx->tlsp = tlsp;
67-
ctx->ip = (unsigned long) asm_thread_starter;
68-
arch_init_extregs(ctx);
62+
UK_ASSERT(sw_ctx != NULL);
6963

70-
save_extregs(ctx);
64+
sw_ctx->sp = sp;
65+
sw_ctx->tlsp = tlsp;
66+
sw_ctx->ip = (unsigned long) asm_thread_starter;
67+
arch_init_extregs(sw_ctx);
7168

72-
return ctx;
69+
save_extregs(sw_ctx);
7370
}
7471

7572
extern void asm_ctx_start(unsigned long sp, unsigned long ip) __noreturn;
@@ -103,7 +100,8 @@ static void sw_ctx_switch(void *prevctx, void *nextctx)
103100
void sw_ctx_callbacks_init(struct ukplat_ctx_callbacks *ctx_cbs)
104101
{
105102
UK_ASSERT(ctx_cbs != NULL);
106-
ctx_cbs->create_cb = sw_ctx_create;
103+
ctx_cbs->size_cb = sw_ctx_size;
104+
ctx_cbs->init_cb = sw_ctx_init;
107105
ctx_cbs->start_cb = sw_ctx_start;
108106
ctx_cbs->switch_cb = sw_ctx_switch;
109107
}

0 commit comments

Comments
 (0)