eal: introduce thread init helper
Introduce a helper responsible for initialising the per thread context. We can then have a unified context for EAL and non-EAL threads and remove copy/paste'd OS-specific helpers. Per EAL thread CPU affinity setting is separated from the thread init. It is to accommodate with Windows EAL where CPU affinity is not set at the moment. Besides, having affinity set by the master lcore in FreeBSD and Linux will make it possible to detect errors rather than panic in the child thread. But the cleanup when such an event happens is left for later. A side-effect of this patch is that control threads can now use recursive locks (rte_gettid() was not called before). Signed-off-by: David Marchand <david.marchand@redhat.com> Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
This commit is contained in:
parent
3ef1a0b4a1
commit
266b641ccf
@ -71,20 +71,10 @@ eal_cpuset_socket_id(rte_cpuset_t *cpusetp)
|
||||
return socket_id;
|
||||
}
|
||||
|
||||
int
|
||||
rte_thread_set_affinity(rte_cpuset_t *cpusetp)
|
||||
static void
|
||||
thread_update_affinity(rte_cpuset_t *cpusetp)
|
||||
{
|
||||
int s;
|
||||
unsigned lcore_id;
|
||||
pthread_t tid;
|
||||
|
||||
tid = pthread_self();
|
||||
|
||||
s = pthread_setaffinity_np(tid, sizeof(rte_cpuset_t), cpusetp);
|
||||
if (s != 0) {
|
||||
RTE_LOG(ERR, EAL, "pthread_setaffinity_np failed\n");
|
||||
return -1;
|
||||
}
|
||||
unsigned int lcore_id = rte_lcore_id();
|
||||
|
||||
/* store socket_id in TLS for quick access */
|
||||
RTE_PER_LCORE(_socket_id) =
|
||||
@ -94,14 +84,24 @@ rte_thread_set_affinity(rte_cpuset_t *cpusetp)
|
||||
memmove(&RTE_PER_LCORE(_cpuset), cpusetp,
|
||||
sizeof(rte_cpuset_t));
|
||||
|
||||
lcore_id = rte_lcore_id();
|
||||
if (lcore_id != (unsigned)LCORE_ID_ANY) {
|
||||
/* EAL thread will update lcore_config */
|
||||
lcore_config[lcore_id].socket_id = RTE_PER_LCORE(_socket_id);
|
||||
memmove(&lcore_config[lcore_id].cpuset, cpusetp,
|
||||
sizeof(rte_cpuset_t));
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
rte_thread_set_affinity(rte_cpuset_t *cpusetp)
|
||||
{
|
||||
if (pthread_setaffinity_np(pthread_self(), sizeof(rte_cpuset_t),
|
||||
cpusetp) != 0) {
|
||||
RTE_LOG(ERR, EAL, "pthread_setaffinity_np failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
thread_update_affinity(cpusetp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -147,6 +147,19 @@ eal_thread_dump_affinity(char *str, unsigned size)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
__rte_thread_init(unsigned int lcore_id, rte_cpuset_t *cpuset)
|
||||
{
|
||||
/* set the lcore ID in per-lcore memory area */
|
||||
RTE_PER_LCORE(_lcore_id) = lcore_id;
|
||||
|
||||
/* acquire system unique id */
|
||||
rte_gettid();
|
||||
|
||||
thread_update_affinity(cpuset);
|
||||
|
||||
__rte_trace_mem_per_thread_alloc();
|
||||
}
|
||||
|
||||
struct rte_thread_ctrl_params {
|
||||
void *(*start_routine)(void *);
|
||||
@ -154,7 +167,7 @@ struct rte_thread_ctrl_params {
|
||||
pthread_barrier_t configured;
|
||||
};
|
||||
|
||||
static void *rte_thread_init(void *arg)
|
||||
static void *ctrl_thread_init(void *arg)
|
||||
{
|
||||
int ret;
|
||||
struct internal_config *internal_conf =
|
||||
@ -164,8 +177,7 @@ static void *rte_thread_init(void *arg)
|
||||
void *(*start_routine)(void *) = params->start_routine;
|
||||
void *routine_arg = params->arg;
|
||||
|
||||
/* Store cpuset in TLS for quick access */
|
||||
memmove(&RTE_PER_LCORE(_cpuset), cpuset, sizeof(rte_cpuset_t));
|
||||
__rte_thread_init(rte_lcore_id(), cpuset);
|
||||
|
||||
ret = pthread_barrier_wait(¶ms->configured);
|
||||
if (ret == PTHREAD_BARRIER_SERIAL_THREAD) {
|
||||
@ -173,8 +185,6 @@ static void *rte_thread_init(void *arg)
|
||||
free(params);
|
||||
}
|
||||
|
||||
__rte_trace_mem_per_thread_alloc();
|
||||
|
||||
return start_routine(routine_arg);
|
||||
}
|
||||
|
||||
@ -198,7 +208,7 @@ rte_ctrl_thread_create(pthread_t *thread, const char *name,
|
||||
|
||||
pthread_barrier_init(¶ms->configured, NULL, 2);
|
||||
|
||||
ret = pthread_create(thread, attr, rte_thread_init, (void *)params);
|
||||
ret = pthread_create(thread, attr, ctrl_thread_init, (void *)params);
|
||||
if (ret != 0) {
|
||||
free(params);
|
||||
return -ret;
|
||||
|
@ -699,4 +699,14 @@ eal_get_internal_configuration(void);
|
||||
rte_usage_hook_t
|
||||
eal_get_application_usage_hook(void);
|
||||
|
||||
/**
|
||||
* Init per-lcore info in current thread.
|
||||
*
|
||||
* @param lcore_id
|
||||
* identifier of lcore.
|
||||
* @param cpuset
|
||||
* CPU affinity for this thread.
|
||||
*/
|
||||
void __rte_thread_init(unsigned int lcore_id, rte_cpuset_t *cpuset);
|
||||
|
||||
#endif /* _EAL_PRIVATE_H_ */
|
||||
|
@ -15,14 +15,6 @@
|
||||
*/
|
||||
__rte_noreturn void *eal_thread_loop(void *arg);
|
||||
|
||||
/**
|
||||
* Init per-lcore info for master thread
|
||||
*
|
||||
* @param lcore_id
|
||||
* identifier of master lcore
|
||||
*/
|
||||
void eal_thread_init_master(unsigned lcore_id);
|
||||
|
||||
/**
|
||||
* Get the NUMA socket id from cpu id.
|
||||
* This function is private to EAL.
|
||||
|
@ -845,7 +845,14 @@ rte_eal_init(int argc, char **argv)
|
||||
|
||||
eal_check_mem_on_local_socket();
|
||||
|
||||
eal_thread_init_master(config->master_lcore);
|
||||
if (pthread_setaffinity_np(pthread_self(), sizeof(rte_cpuset_t),
|
||||
&lcore_config[config->master_lcore].cpuset) != 0) {
|
||||
rte_eal_init_alert("Cannot set affinity");
|
||||
rte_errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
__rte_thread_init(config->master_lcore,
|
||||
&lcore_config[config->master_lcore].cpuset);
|
||||
|
||||
ret = eal_thread_dump_affinity(cpuset, sizeof(cpuset));
|
||||
|
||||
@ -876,6 +883,11 @@ rte_eal_init(int argc, char **argv)
|
||||
snprintf(thread_name, sizeof(thread_name),
|
||||
"lcore-slave-%d", i);
|
||||
rte_thread_setname(lcore_config[i].thread_id, thread_name);
|
||||
|
||||
ret = pthread_setaffinity_np(lcore_config[i].thread_id,
|
||||
sizeof(rte_cpuset_t), &lcore_config[i].cpuset);
|
||||
if (ret != 0)
|
||||
rte_panic("Cannot set affinity\n");
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -66,29 +66,6 @@ rte_eal_remote_launch(int (*f)(void *), void *arg, unsigned slave_id)
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* set affinity for current thread */
|
||||
static int
|
||||
eal_thread_set_affinity(void)
|
||||
{
|
||||
unsigned lcore_id = rte_lcore_id();
|
||||
|
||||
/* acquire system unique id */
|
||||
rte_gettid();
|
||||
|
||||
/* update EAL thread core affinity */
|
||||
return rte_thread_set_affinity(&lcore_config[lcore_id].cpuset);
|
||||
}
|
||||
|
||||
void eal_thread_init_master(unsigned lcore_id)
|
||||
{
|
||||
/* set the lcore ID in per-lcore memory area */
|
||||
RTE_PER_LCORE(_lcore_id) = lcore_id;
|
||||
|
||||
/* set CPU affinity */
|
||||
if (eal_thread_set_affinity() < 0)
|
||||
rte_panic("cannot set affinity\n");
|
||||
}
|
||||
|
||||
/* main loop of threads */
|
||||
__rte_noreturn void *
|
||||
eal_thread_loop(__rte_unused void *arg)
|
||||
@ -113,19 +90,12 @@ eal_thread_loop(__rte_unused void *arg)
|
||||
m2s = lcore_config[lcore_id].pipe_master2slave[0];
|
||||
s2m = lcore_config[lcore_id].pipe_slave2master[1];
|
||||
|
||||
/* set the lcore ID in per-lcore memory area */
|
||||
RTE_PER_LCORE(_lcore_id) = lcore_id;
|
||||
|
||||
/* set CPU affinity */
|
||||
if (eal_thread_set_affinity() < 0)
|
||||
rte_panic("cannot set affinity\n");
|
||||
__rte_thread_init(lcore_id, &lcore_config[lcore_id].cpuset);
|
||||
|
||||
ret = eal_thread_dump_affinity(cpuset, sizeof(cpuset));
|
||||
|
||||
RTE_LOG(DEBUG, EAL, "lcore %u is ready (tid=%p;cpuset=[%s%s])\n",
|
||||
lcore_id, thread_id, cpuset, ret == 0 ? "" : "...");
|
||||
|
||||
__rte_trace_mem_per_thread_alloc();
|
||||
rte_eal_trace_thread_lcore_ready(lcore_id, cpuset);
|
||||
|
||||
/* read on our pipe to get commands */
|
||||
|
@ -1209,10 +1209,16 @@ rte_eal_init(int argc, char **argv)
|
||||
|
||||
eal_check_mem_on_local_socket();
|
||||
|
||||
eal_thread_init_master(config->master_lcore);
|
||||
if (pthread_setaffinity_np(pthread_self(), sizeof(rte_cpuset_t),
|
||||
&lcore_config[config->master_lcore].cpuset) != 0) {
|
||||
rte_eal_init_alert("Cannot set affinity");
|
||||
rte_errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
__rte_thread_init(config->master_lcore,
|
||||
&lcore_config[config->master_lcore].cpuset);
|
||||
|
||||
ret = eal_thread_dump_affinity(cpuset, sizeof(cpuset));
|
||||
|
||||
RTE_LOG(DEBUG, EAL, "Master lcore %u is ready (tid=%zx;cpuset=[%s%s])\n",
|
||||
config->master_lcore, (uintptr_t)thread_id, cpuset,
|
||||
ret == 0 ? "" : "...");
|
||||
@ -1244,6 +1250,11 @@ rte_eal_init(int argc, char **argv)
|
||||
if (ret != 0)
|
||||
RTE_LOG(DEBUG, EAL,
|
||||
"Cannot set name for lcore thread\n");
|
||||
|
||||
ret = pthread_setaffinity_np(lcore_config[i].thread_id,
|
||||
sizeof(rte_cpuset_t), &lcore_config[i].cpuset);
|
||||
if (ret != 0)
|
||||
rte_panic("Cannot set affinity\n");
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -66,29 +66,6 @@ rte_eal_remote_launch(int (*f)(void *), void *arg, unsigned slave_id)
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* set affinity for current EAL thread */
|
||||
static int
|
||||
eal_thread_set_affinity(void)
|
||||
{
|
||||
unsigned lcore_id = rte_lcore_id();
|
||||
|
||||
/* acquire system unique id */
|
||||
rte_gettid();
|
||||
|
||||
/* update EAL thread core affinity */
|
||||
return rte_thread_set_affinity(&lcore_config[lcore_id].cpuset);
|
||||
}
|
||||
|
||||
void eal_thread_init_master(unsigned lcore_id)
|
||||
{
|
||||
/* set the lcore ID in per-lcore memory area */
|
||||
RTE_PER_LCORE(_lcore_id) = lcore_id;
|
||||
|
||||
/* set CPU affinity */
|
||||
if (eal_thread_set_affinity() < 0)
|
||||
rte_panic("cannot set affinity\n");
|
||||
}
|
||||
|
||||
/* main loop of threads */
|
||||
__rte_noreturn void *
|
||||
eal_thread_loop(__rte_unused void *arg)
|
||||
@ -113,19 +90,12 @@ eal_thread_loop(__rte_unused void *arg)
|
||||
m2s = lcore_config[lcore_id].pipe_master2slave[0];
|
||||
s2m = lcore_config[lcore_id].pipe_slave2master[1];
|
||||
|
||||
/* set the lcore ID in per-lcore memory area */
|
||||
RTE_PER_LCORE(_lcore_id) = lcore_id;
|
||||
|
||||
/* set CPU affinity */
|
||||
if (eal_thread_set_affinity() < 0)
|
||||
rte_panic("cannot set affinity\n");
|
||||
__rte_thread_init(lcore_id, &lcore_config[lcore_id].cpuset);
|
||||
|
||||
ret = eal_thread_dump_affinity(cpuset, sizeof(cpuset));
|
||||
|
||||
RTE_LOG(DEBUG, EAL, "lcore %u is ready (tid=%zx;cpuset=[%s%s])\n",
|
||||
lcore_id, (uintptr_t)thread_id, cpuset, ret == 0 ? "" : "...");
|
||||
|
||||
__rte_trace_mem_per_thread_alloc();
|
||||
rte_eal_trace_thread_lcore_ready(lcore_id, cpuset);
|
||||
|
||||
/* read on our pipe to get commands */
|
||||
|
@ -333,7 +333,8 @@ rte_eal_init(int argc, char **argv)
|
||||
return -1;
|
||||
}
|
||||
|
||||
eal_thread_init_master(config->master_lcore);
|
||||
__rte_thread_init(config->master_lcore,
|
||||
&lcore_config[config->master_lcore].cpuset);
|
||||
|
||||
bscan = rte_bus_scan();
|
||||
if (bscan < 0) {
|
||||
|
@ -53,13 +53,6 @@ rte_eal_remote_launch(lcore_function_t *f, void *arg, unsigned int slave_id)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
eal_thread_init_master(unsigned int lcore_id)
|
||||
{
|
||||
/* set the lcore ID in per-lcore memory area */
|
||||
RTE_PER_LCORE(_lcore_id) = lcore_id;
|
||||
}
|
||||
|
||||
/* main loop of threads */
|
||||
void *
|
||||
eal_thread_loop(void *arg __rte_unused)
|
||||
@ -84,8 +77,7 @@ eal_thread_loop(void *arg __rte_unused)
|
||||
m2s = lcore_config[lcore_id].pipe_master2slave[0];
|
||||
s2m = lcore_config[lcore_id].pipe_slave2master[1];
|
||||
|
||||
/* set the lcore ID in per-lcore memory area */
|
||||
RTE_PER_LCORE(_lcore_id) = lcore_id;
|
||||
__rte_thread_init(lcore_id, &lcore_config[lcore_id].cpuset);
|
||||
|
||||
RTE_LOG(DEBUG, EAL, "lcore %u is ready (tid=%zx;cpuset=[%s])\n",
|
||||
lcore_id, (uintptr_t)thread_id, cpuset);
|
||||
|
Loading…
Reference in New Issue
Block a user