Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OP-TEE benchmark: initial benchmark app #1

Merged
merged 1 commit into from
May 31, 2017
Merged

Conversation

igoropaniuk
Copy link

@igoropaniuk igoropaniuk commented Feb 22, 2017

Related PRs:

Benchmark app:
#1

Changes in OP-TEE
linaro-swg/linux#38
OP-TEE/build#124
OP-TEE/optee_os#1365
OP-TEE/optee_client#79

Dedicated repo manifest (for testing):

repo init -u https://github.com/igoropaniuk/manifest.git -m qemu_v7_benchmark.xml -b benchmark

Invocation:

# benchmark client_app [client_app params]

Example:

# benchmark ./xtest 1001

Signed-off-by: Igor Opaniuk [email protected]

@igoropaniuk igoropaniuk changed the title Add initial benchmark app [RFC] OP-TEE benchmark: initial benchmark app Feb 22, 2017
@igoropaniuk igoropaniuk force-pushed the optee_benchmark branch 2 times, most recently from 7a91cb4 to 9fa484c Compare February 22, 2017 20:26
@igoropaniuk igoropaniuk changed the title [RFC] OP-TEE benchmark: initial benchmark app OP-TEE benchmark: initial benchmark app Apr 18, 2017
main.c Outdated
&ts_data);
if (!ret) {
ts_received = true;
printf("Timestamp CPU = %ld"
Copy link
Author

@igoropaniuk igoropaniuk Apr 19, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding now code for dumping timestamps to CSV file instead of this debug output

@igoropaniuk
Copy link
Author

@etienne-lms @jenswi-linaro Could check please also this PR, it includes almost 40-50% of the functionality. Thanks

Copy link
Contributor

@etienne-lms etienne-lms left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks ok.
Nice to benchmark a specific executable file.

Maybe the benchmark tool could also enable benchmark and sleep until it is killed. Launching benchmark --enable would allow benchmarking already running CAs and TAs.

benchmark_aux.c Outdated

testapp_argv[i - 1] = malloc(length);
if (i == 1)
memcpy(testapp_argv[i-1], base, strlen(base) + 1);
Copy link
Contributor

@etienne-lms etienne-lms Apr 19, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Allocate strlen(base) for testapp_argv[0]. Maybe argv0 should be processed before the for loop.

@igoropaniuk
Copy link
Author

Maybe the benchmark tool could also enable benchmark and sleep until it is killed. Launching benchmark --enable would allow benchmarking already running CAs and TAs.

@etienne-lms Good idea, why not. Anyway, an app collects system-wide timestamps in both cases

@etienne-lms
Copy link
Contributor

Don't it be hard to find which timestamp belong to which TEE session ? Adding a session ID to stamps could even help filtering out sessions for which no time-stamping is requested.

Copy link
Contributor

@etienne-lms etienne-lms left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 extra minor comments.

main.c Outdated
if (pthread_join(consumer_thread, NULL)) {
fprintf(stderr, "Error joining thread\n");
return 2;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor: empty line

main.c Outdated
else {
execvp(testapp_path, testapp_argv);
tee_errx("execve() failed", EXIT_FAILURE);
_exit(EXIT_FAILURE);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor: useless _exit();

main.c Outdated
static TEEC_SharedMemory ts_buf_shm = {
.flags = TEEC_MEM_INPUT | TEEC_MEM_OUTPUT,
.buffer = NULL,
.size = 0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor: these 2 inits are useless.

main.c Outdated
uint32_t ret_orig;

ts_buf_shm.size = sizeof(struct tee_ts_global)
+ sizeof(struct tee_ts_cpu_buf) * cores;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: prefer the + sign at the end of the former line.

main.c Outdated
op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_INOUT,
TEEC_NONE, TEEC_NONE, TEEC_NONE);
op.params[0].memref.parent = &ts_buf_shm;
op.params[0].memref.offset = 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: no need to set offset to 0.

return RING_BADPARM;

if (cpu_buf->tail >= cpu_buf->head)
return RING_NODATA;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As referencing a ring buffer, tail might get higher than head and buffer can still hold valid content.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

both head and tail are uint64_t, and they are not actually an index in the circular buffer. Index is ts_i & TEE_BENCH_MAX_MASK

tail might get higher than head and buffer can still hold valid content.

this could be true only if head overflows, which is almost an impossible case, if to consider an intensity of adding timestamps

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I see your scheme.
So you can detect overflows of the buffers from (head - tail > TEE_BENCH_MAX_MASK).

Since pushing and poping data to ts buffer are concurrent, I think you insure the poped data are valid before storing them into the benchmark data file:

  1. If no data (tail>=head), return with "no data".
  2. Locally store ts data referred by tail.
  3. Check for overflow (head - tail > TEE_BENCH_MAX_MASK)
    If no overflow (then previous stored ts data are valid): increment tail and return the previously locally stored ts data.
    If overflow found, update tail = head - TEE_BENCH_MAX_MASK, and return with a overflow status.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@etienne-lms

let's keep it as known limitation for now, I'll add support for it in future PRs, OK?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok

main.c Outdated
struct tee_time_st *ts)
{
struct tee_time_st ts_data;
uint64_t ts_tail = 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor: these 2 are quite useless.

if (cpu_buf->tail >= cpu_buf->head)
return RING_NODATA;

ts_tail = cpu_buf->tail++;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If tail is higher than TEE_BENCH_MAX_MASK, it should get back to 0.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not necessarily, because

ts_data = cpu_buf->stamps[ts_tail & TEE_BENCH_MAX_MASK];

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, agree. sorry.

tee_errx(errmsg, res);
}

const char *bench_str_src(uint64_t source)
Copy link
Contributor

@jbech-linaro jbech-linaro Apr 27, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't it be better to just simply use a lookup table in terms on a const char array? (Only drawback is not being able to catch "???").

Copy link
Contributor

@jbech-linaro jbech-linaro Apr 27, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This wasn't a good suggestion. Since the defined values or not simply from 0 to 4, you cannot use a lookup table. Having that said is there a good reason to have the values defined as (instead of 0 to 4)?

+/* OP-TEE susbsystems ids */
 +#define TEE_BENCH_CLIENT	0x10000000
 +#define TEE_BENCH_KMOD		0x20000000
 +#define TEE_BENCH_CORE		0x30000000
 +#define TEE_BENCH_UTEE		0x40000000
 +#define TEE_BENCH_DUMB_TA	0xF0000001

main.c Outdated

#define STAT_AMOUNT 5

#define RING_SUCCESS 0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The indentation for the defines here and below are a bit weird (random spacing).

main.c Outdated

#define TSFILE_NAME_SUFFIX ".ts"
static const TEEC_UUID pta_benchmark_uuid = PTA_BENCHMARK_UUID;
struct tee_ts_global *bench_ts_global;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I cannot find where you've declared struct tee_ts_global? I can see further down that you do for example

static void init_ts_global(struct tee_ts_global *ts_global,
                                uint32_t cores)
{
...
  /* init global timestamp buffer */
  bench_ts_global = ts_global;
  bench_ts_global->cores = cores;
...
}

What do I miss here? (I've tried to grep for it also).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nevermind, I found it in the public/tee_bench.h in the optee_client PR ...

main.c Outdated
res = TEEC_AllocateSharedMemory(&ctx, &ts_buf_shm);
tee_check_res(res, "TEEC_AllocateSharedMemory");

init_ts_global((struct tee_ts_global *)ts_buf_shm.buffer, cores);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment is maybe a bit overkill / personal preference. But the intention with this function call is to take a buffer and transform it into a time stamp buffer. For me it sounds like this should be a void * when calling this function and after that we can refer to it as a struct tee_ts_global * buffer.

I.e, what I'm saying is, that I think I'd have changed init_ts_globalto:

static void init_ts_global(void *buf, uint32_t cores)

main.c Outdated

TEEC_InvokeCommand(&sess, BENCHMARK_CMD_REGISTER_MEMREF,
&op, &ret_orig);
tee_check_res(res, "TEEC_InvokeCommand");
Copy link
Contributor

@jbech-linaro jbech-linaro Apr 27, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not a big fan of the debug prints here, since you can't tell the difference between them (this and the one on line 143 for example will print the same). Not a big deal for this particular PR/commit. But I think we should address this as soon as possible after merging this.

@igoropaniuk
Copy link
Author

Don't it be hard to find which timestamp belong to which TEE session ? Adding a session ID to stamps could even help filtering out sessions for which no time-stamping is requested.

@etienne-lms Now we have a pretty generic bm_timestamp implementation, which can be theoretically called within anywhere in OP-TEE OS, Linux kernel, and optee_client, and not only in functions, that are related to InvokeCommand/OpenSession calls.

In the future, I plan to add ability to attach some payload to each timestamp, which can be TEE_Session id, whatever.

@igoropaniuk
Copy link
Author

@etienne-lms

Maybe the benchmark tool could also enable benchmark and sleep until it is killed. Launching benchmark --enable would allow benchmarking already running CAs and TAs.

I thinks maybe let's add it in future PRs?

@jbech-linaro
Copy link
Contributor

Maybe the benchmark tool could also enable benchmark and sleep until it is killed. Launching benchmark --enable would allow benchmarking already running CAs and TAs.
I thinks maybe let's add it in future PRs?

Agreed! Let's try to get the main patches merged so that we can start working with smaller and more well defined tasks.

@etienne-lms
Copy link
Contributor

Reviewed-by: Etienne Carriere <[email protected]>

optee_benchmark application handles all provided timestamp data for the
roundtrip time from libteec to OP-TEE OS core.

Reviewed-by: Etienne Carriere <[email protected]>
Signed-off-by: Igor Opaniuk <[email protected]>
@igoropaniuk
Copy link
Author

Tags applied, ready for merge

@igoropaniuk igoropaniuk merged commit ab88c95 into master May 31, 2017
@igoropaniuk
Copy link
Author

Merged

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants