Patchwork MARS: Kernel syscall add get workload by id

login
register
mail settings
Submitter Yuji Mano
Date Sept. 11, 2008, 7:34 p.m.
Message ID <48C972D7.3030009@am.sony.com>
Download mbox | patch
Permalink /patch/238/
State New
Delegated to: Yuji Mano
Headers show

Comments

Yuji Mano - Sept. 11, 2008, 7:34 p.m.
This adds a new MARS kernel syscall 'mars_get_workload_by_id' to allow for the
task library to grab an instance of a workload context other than the one
currently running. This is needed when a task waits for completion of another
task, and needs to obtain the exit_code of the completed task from the task
context.

This also renames the previously existing MARS kernel syscall
'mars_get_workload_context' to 'mars_get_workload'.

Signed-off-by: Yuji Mano <yuji.mano@am.sony.com>
Kazunori Asayama - Sept. 12, 2008, 7:30 a.m.
Yuji Mano wrote:
> This adds a new MARS kernel syscall 'mars_get_workload_by_id' to allow for the
> task library to grab an instance of a workload context other than the one
> currently running. This is needed when a task waits for completion of another
> task, and needs to obtain the exit_code of the completed task from the task
> context.
> 
> This also renames the previously existing MARS kernel syscall
> 'mars_get_workload_context' to 'mars_get_workload'.
> 
> Signed-off-by: Yuji Mano <yuji.mano@am.sony.com>

(snip)

> +struct mars_workload_context *workload_get_by_id(uint16_t workload_id)
> +{
> +	MARS_CHECK_RET(workload_id < MARS_WORKLOAD_MAX, NULL);
> +
> +	static struct mars_workload_context requested_workload;
> +	uint64_t requested_workload_ea;
> +
> +	/* workload id is same as current workload so return local copy */
> +	if (workload_id == workload_index)
> +		return &workload;
> +
> +	/* get ea of workload to get */
> +	requested_workload_ea = queue_header.context_ea +
> +			workload_id * sizeof(struct mars_workload_context);
> +
> +	/* dma the workload context code into LS from main memory */
> +	mars_dma_get_and_wait((void *)&requested_workload,
> +				requested_workload_ea,
> +				sizeof(struct mars_workload_context),
> +				MARS_DMA_TAG);
> +
> +	return &requested_workload;
> +}
> +

The static area 'requested_workload' can be overwritten by the next
workload_get_by_id call. Is it OK?
Yuji Mano - Sept. 12, 2008, 9:18 p.m.
Kazunori Asayama wrote:
> Yuji Mano wrote:
>> This adds a new MARS kernel syscall 'mars_get_workload_by_id' to allow for the
>> task library to grab an instance of a workload context other than the one
>> currently running. This is needed when a task waits for completion of another
>> task, and needs to obtain the exit_code of the completed task from the task
>> context.
>> 
>> This also renames the previously existing MARS kernel syscall
>> 'mars_get_workload_context' to 'mars_get_workload'.
>> 
>> Signed-off-by: Yuji Mano <yuji.mano@am.sony.com>
> 
> (snip)
> 
>> +struct mars_workload_context *workload_get_by_id(uint16_t workload_id)
>> +{
>> +	MARS_CHECK_RET(workload_id < MARS_WORKLOAD_MAX, NULL);
>> +
>> +	static struct mars_workload_context requested_workload;
>> +	uint64_t requested_workload_ea;
>> +
>> +	/* workload id is same as current workload so return local copy */
>> +	if (workload_id == workload_index)
>> +		return &workload;
>> +
>> +	/* get ea of workload to get */
>> +	requested_workload_ea = queue_header.context_ea +
>> +			workload_id * sizeof(struct mars_workload_context);
>> +
>> +	/* dma the workload context code into LS from main memory */
>> +	mars_dma_get_and_wait((void *)&requested_workload,
>> +				requested_workload_ea,
>> +				sizeof(struct mars_workload_context),
>> +				MARS_DMA_TAG);
>> +
>> +	return &requested_workload;
>> +}
>> +
> 
> The static area 'requested_workload' can be overwritten by the next
> workload_get_by_id call. Is it OK?
> 

In the current implementation this is not a problem.
But of course the caller needs to be aware that the context ptr returned
is only valid until the next call to that function. Currently the task
policy uses this only so it can get the exit_code out from the context and
does not keep the returned pointer around. 

I think this is fine for now because this syscall is available only between
the kernel and the runtime policy internal implementation and not made
available publicly.

If and when we decide to provide a custom policy module interface, this
may need to change for more flexibility.

Regards,
Yuji
Kazunori Asayama - Sept. 16, 2008, 6:43 a.m.
Yuji Mano wrote:
> Kazunori Asayama wrote:
>> The static area 'requested_workload' can be overwritten by the next
>> workload_get_by_id call. Is it OK?
>>
> 
> In the current implementation this is not a problem.
> But of course the caller needs to be aware that the context ptr returned
> is only valid until the next call to that function. Currently the task
> policy uses this only so it can get the exit_code out from the context and
> does not keep the returned pointer around. 
> 
> I think this is fine for now because this syscall is available only between
> the kernel and the runtime policy internal implementation and not made
> available publicly.

OK, agreed.

> 
> If and when we decide to provide a custom policy module interface, this
> may need to change for more flexibility.

Or just we can say about this restriction in the reference manual.
Kazunori Asayama - Sept. 16, 2008, 6:43 a.m.
Yuji Mano wrote:
> This adds a new MARS kernel syscall 'mars_get_workload_by_id' to allow for the
> task library to grab an instance of a workload context other than the one
> currently running. This is needed when a task waits for completion of another
> task, and needs to obtain the exit_code of the completed task from the task
> context.
> 
> This also renames the previously existing MARS kernel syscall
> 'mars_get_workload_context' to 'mars_get_workload'.
> 
> Signed-off-by: Yuji Mano <yuji.mano@am.sony.com>

Acked-by: Kazunori Asayama <asayama@sm.sony.co.jp>

> 
> ---
>  include/mpu/mars/mars_kernel.h        |   10 +++++++---
>  include/mpu/mars/mars_syscalls.h      |    3 ++-
>  src/mpu/kernel/mars_kernel_syscalls.c |   12 +++++++++---
>  src/mpu/kernel/mars_kernel_workload.c |   26 +++++++++++++++++++++++++-
>  src/mpu/lib/mars_syscalls.c           |    9 +++++++--
>  src/mpu/lib/mars_task.c               |    8 ++++----
>  src/mpu/lib/mars_task_barrier.c       |    4 ++--
>  src/mpu/lib/mars_task_event_flag.c    |    2 +-
>  src/mpu/lib/mars_task_queue.c         |    2 +-
>  src/mpu/lib/mars_task_semaphore.c     |    2 +-
>  src/mpu/lib/mars_task_signal.c        |    2 +-
>  11 files changed, 60 insertions(+), 20 deletions(-)
>

Patch

--- a/include/mpu/mars/mars_kernel.h
+++ b/include/mpu/mars/mars_kernel.h
@@ -62,7 +62,9 @@  struct mars_kernel_syscalls {
 	uint32_t (*get_kernel_id)(void);
 	uint16_t (*get_workload_id)(void);
 	uint64_t (*get_workload_ea)(void);
-	struct mars_workload_context *(*get_workload_context)(void);
+	struct mars_workload_context *(*get_workload)(void);
+	struct mars_workload_context *(*get_workload_by_id)
+		(uint16_t workload_id);
 
 	void (*init)(void);
 	void (*exit)(void);
@@ -86,7 +88,8 @@  uint64_t syscall_get_mars_context_ea(voi
 uint32_t syscall_get_kernel_id(void);
 uint16_t syscall_get_workload_id(void);
 uint64_t syscall_get_workload_ea(void);
-struct mars_workload_context *syscall_get_workload_context(void);
+struct mars_workload_context *syscall_get_workload(void);
+struct mars_workload_context *syscall_get_workload_by_id(uint16_t workload_id);
 
 void syscall_setup(void);
 void syscall_init(void);
@@ -107,7 +110,8 @@  void registers_restore(void);
 /* workload specific functions */
 uint16_t workload_get_id(void);
 uint64_t workload_get_ea(void);
-struct mars_workload_context * workload_get_context(void);
+struct mars_workload_context *workload_get(void);
+struct mars_workload_context *workload_get_by_id(uint16_t workload_id);
 
 void workload_exec(void);
 void workload_exit(void);
--- a/include/mpu/mars/mars_syscalls.h
+++ b/include/mpu/mars/mars_syscalls.h
@@ -48,7 +48,8 @@  uint64_t mars_get_mars_context_ea(void);
 uint32_t mars_get_kernel_id(void);
 uint16_t mars_get_workload_id(void);
 uint64_t mars_get_workload_ea(void);
-struct mars_workload_context *mars_get_workload_context(void);
+struct mars_workload_context *mars_get_workload(void);
+struct mars_workload_context *mars_get_workload_by_id(uint16_t workload_id);
 
 void mars_init(void);
 void mars_exit(void);
--- a/src/mpu/kernel/mars_kernel_syscalls.c
+++ b/src/mpu/kernel/mars_kernel_syscalls.c
@@ -53,7 +53,8 @@  void syscall_setup(void)
 	kernel_syscalls.get_kernel_id		= syscall_get_kernel_id;
 	kernel_syscalls.get_workload_id		= syscall_get_workload_id;
 	kernel_syscalls.get_workload_ea		= syscall_get_workload_ea;
-	kernel_syscalls.get_workload_context	= syscall_get_workload_context;
+	kernel_syscalls.get_workload		= syscall_get_workload;
+	kernel_syscalls.get_workload_by_id	= syscall_get_workload_by_id;
 	kernel_syscalls.init			= syscall_init;
 	kernel_syscalls.exit			= syscall_exit;
 	kernel_syscalls.yield			= syscall_yield;
@@ -85,9 +86,14 @@  uint64_t syscall_get_workload_ea(void)
 	return workload_get_ea();
 }
 
-struct mars_workload_context *syscall_get_workload_context(void)
+struct mars_workload_context *syscall_get_workload(void)
 {
-	return workload_get_context();
+	return workload_get();
+}
+
+struct mars_workload_context *syscall_get_workload_by_id(uint16_t workload_id)
+{
+	return workload_get_by_id(workload_id);
 }
 
 void syscall_init(void)
--- a/src/mpu/kernel/mars_kernel_workload.c
+++ b/src/mpu/kernel/mars_kernel_workload.c
@@ -55,11 +55,35 @@  uint64_t workload_get_ea(void)
 	return workload_ea;
 }
 
-struct mars_workload_context *workload_get_context(void)
+struct mars_workload_context *workload_get(void)
 {
 	return &workload;
 }
 
+struct mars_workload_context *workload_get_by_id(uint16_t workload_id)
+{
+	MARS_CHECK_RET(workload_id < MARS_WORKLOAD_MAX, NULL);
+
+	static struct mars_workload_context requested_workload;
+	uint64_t requested_workload_ea;
+
+	/* workload id is same as current workload so return local copy */
+	if (workload_id == workload_index)
+		return &workload;
+
+	/* get ea of workload to get */
+	requested_workload_ea = queue_header.context_ea +
+			workload_id * sizeof(struct mars_workload_context);
+
+	/* dma the workload context code into LS from main memory */
+	mars_dma_get_and_wait((void *)&requested_workload,
+				requested_workload_ea,
+				sizeof(struct mars_workload_context),
+				MARS_DMA_TAG);
+
+	return &requested_workload;
+}
+
 void workload_exec(void)
 {
 	/* set current workload state to running */
--- a/src/mpu/lib/mars_syscalls.c
+++ b/src/mpu/lib/mars_syscalls.c
@@ -60,9 +60,14 @@  uint64_t mars_get_workload_ea(void)
 	return (*mars_kernel_syscalls->get_workload_ea)();
 }
 
-struct mars_workload_context *mars_get_workload_context(void)
+struct mars_workload_context *mars_get_workload(void)
 {
-	return (*mars_kernel_syscalls->get_workload_context)();
+	return (*mars_kernel_syscalls->get_workload)();
+}
+
+struct mars_workload_context *mars_get_workload_by_id(uint16_t workload_id)
+{
+	return (*mars_kernel_syscalls->get_workload_by_id)(workload_id);
 }
 
 void mars_init(void)
--- a/src/mpu/lib/mars_task.c
+++ b/src/mpu/lib/mars_task.c
@@ -50,7 +50,7 @@  int mars_task_yield(void)
 {
 	struct mars_task_context *task;
 
-	task = (struct mars_task_context *)mars_get_workload_context();
+	task = (struct mars_task_context *)mars_get_workload();
 
 	/* make sure task context has a context save area */
 	MARS_CHECK_RET(task->context_save_size && task->context_save_area,
@@ -77,7 +77,7 @@  int mars_task_wait(struct mars_task_id *
 	int ret;
 	struct mars_task_context *task;
 
-	task = (struct mars_task_context *)mars_get_workload_context();
+	task = (struct mars_task_context *)mars_get_workload();
 
 	/* make sure task context has a context save area */
 	MARS_CHECK_RET(task->context_save_size && task->context_save_area,
@@ -107,7 +107,7 @@  const struct mars_task_id *mars_task_get
 {
 	struct mars_task_context *task;
 
-	task = (struct mars_task_context *)mars_get_workload_context();
+	task = (struct mars_task_context *)mars_get_workload();
 
 	return &task->id;
 }
@@ -116,7 +116,7 @@  const char *mars_task_get_name(void)
 {
 	struct mars_task_context *task;
 
-	task = (struct mars_task_context *)mars_get_workload_context();
+	task = (struct mars_task_context *)mars_get_workload();
 
 	return (const char *)task->id.name;
 }
--- a/src/mpu/lib/mars_task_barrier.c
+++ b/src/mpu/lib/mars_task_barrier.c
@@ -75,7 +75,7 @@  int mars_task_barrier_notify(uint64_t ba
 	int i;
 	struct mars_task_context *task;
 
-	task = (struct mars_task_context *)mars_get_workload_context();
+	task = (struct mars_task_context *)mars_get_workload();
 
 	/* make sure task context has a context save area */
 	MARS_CHECK_RET(task->context_save_size && task->context_save_area,
@@ -157,7 +157,7 @@  int mars_task_barrier_wait(uint64_t barr
 	int i;
 	struct mars_task_context *task;
 
-	task = (struct mars_task_context *)mars_get_workload_context();
+	task = (struct mars_task_context *)mars_get_workload();
 
 	/* make sure task context has a context save area */
 	MARS_CHECK_RET(task->context_save_size && task->context_save_area,
--- a/src/mpu/lib/mars_task_event_flag.c
+++ b/src/mpu/lib/mars_task_event_flag.c
@@ -172,7 +172,7 @@  int mars_task_event_flag_wait(uint64_t e
 	int wait = 0;
 	struct mars_task_context *task;
 
-	task = (struct mars_task_context *)mars_get_workload_context();
+	task = (struct mars_task_context *)mars_get_workload();
 
 	/* make sure task context has a context save area */
 	MARS_CHECK_RET(task->context_save_size && task->context_save_area,
--- a/src/mpu/lib/mars_task_queue.c
+++ b/src/mpu/lib/mars_task_queue.c
@@ -296,7 +296,7 @@  static int pop(uint64_t queue_ea, void *
 
 	struct mars_task_context *task;
 
-	task = (struct mars_task_context *)mars_get_workload_context();
+	task = (struct mars_task_context *)mars_get_workload();
 
 	/* make sure task context has a context save area */
 	MARS_CHECK_RET(task->context_save_size && task->context_save_area,
--- a/src/mpu/lib/mars_task_semaphore.c
+++ b/src/mpu/lib/mars_task_semaphore.c
@@ -75,7 +75,7 @@  int mars_task_semaphore_acquire(uint64_t
 
 	struct mars_task_context *task;
 
-	task = (struct mars_task_context *)mars_get_workload_context();
+	task = (struct mars_task_context *)mars_get_workload();
 
 	/* make sure task context has a context save area */
 	MARS_CHECK_RET(task->context_save_size && task->context_save_area,
--- a/src/mpu/lib/mars_task_signal.c
+++ b/src/mpu/lib/mars_task_signal.c
@@ -52,7 +52,7 @@  int mars_task_signal_wait(void)
 {
 	struct mars_task_context *task;
 
-	task = (struct mars_task_context *)mars_get_workload_context();
+	task = (struct mars_task_context *)mars_get_workload();
 
 	/* make sure task context has a context save area */
 	MARS_CHECK_RET(task->context_save_size && task->context_save_area,