Since this patch requires the API change it would be better to send those two together as a patch set. See other comments below.
> -----Original Message----- > From: EXT Gary S. Robertson [mailto:gary.robert...@linaro.org] > Sent: Saturday, January 23, 2016 1:38 AM > To: mike.hol...@linaro.org; bill.fischo...@linaro.org; > maxim.uva...@linaro.org; anders.rox...@linaro.org; > stuart.has...@linaro.org; petri.savolai...@linaro.org > Cc: lng-odp@lists.linaro.org; Gary S. Robertson > Subject: [lng-odp][API_NEXT PATCH V3 01/01] linux-generic: add support for > initial cpumasks > > These code changes depend on the addition of control and worker > cpumask pointers to the ODP initialization parameter data structure, > and implement the change in behavior suggested with that patch. > They serve as the 'glue' between the input of the new ODP API > initial cpuset masks and the use of those new cpumasks by the > ODP application or instance. > > Specifically: if both of the cpumask pointers are NULL or > if neither of the new cpumasks are populated prior to > calling odp_init_global(), then the behavior for allocation of > control and worker cpumasks is unchanged from its current > (pre-patch) state. > > However, if the cpumasks are populated and their pointers initialized > prior to calling odp_init_global() then that routine saves > their contents into global variables for later reference. > Then when odp_cpumask_default_control() or odp_cpumask_default_worker() > are called they build the caller's cpumasks based on the > saved contents of the pre-populated cpumask input. > > These changes allow multiple concurrent ODP applications > or instances to be given CPU resources which do not conflict > with one another, so multiple ODP instances can coexist harmoniously > with any isolation support on the underlying platform > as well as with one another. > > Signed-off-by: Gary S. Robertson <gary.robert...@linaro.org> > --- > platform/linux-generic/include/odp_internal.h | 2 ++ > platform/linux-generic/odp_cpumask_task.c | 48 > ++++++++++++++++++++++----- > platform/linux-generic/odp_init.c | 19 +++++++++++ > platform/linux-generic/odp_system_info.c | 13 +++----- > 4 files changed, 65 insertions(+), 17 deletions(-) > > diff --git a/platform/linux-generic/include/odp_internal.h > b/platform/linux-generic/include/odp_internal.h > index cdbed7d..7488b3b 100644 > --- a/platform/linux-generic/include/odp_internal.h > +++ b/platform/linux-generic/include/odp_internal.h > @@ -38,6 +38,8 @@ struct odp_global_data_s { > odp_log_func_t log_fn; > odp_abort_func_t abort_fn; > odp_system_info_t system_info; > + odp_cpumask_t control_cpus; > + odp_cpumask_t worker_cpus; > }; > > enum init_stage { > diff --git a/platform/linux-generic/odp_cpumask_task.c b/platform/linux- > generic/odp_cpumask_task.c > index c5093e0..a5a9791 100644 > --- a/platform/linux-generic/odp_cpumask_task.c > +++ b/platform/linux-generic/odp_cpumask_task.c > @@ -17,10 +17,27 @@ int odp_cpumask_default_worker(odp_cpumask_t *mask, > int num) > int ret, cpu, i; > cpu_set_t cpuset; > > - ret = pthread_getaffinity_np(pthread_self(), > - sizeof(cpu_set_t), &cpuset); > - if (ret != 0) > - ODP_ABORT("failed to read CPU affinity value\n"); > + CPU_ZERO(&cpuset); > + > + /* > + * If the available worker cpumask was specified prior to global > init, > + * then allocate worker CPUs from that cpumask. > + */ > + if (odp_cpumask_count(&odp_global_data.worker_cpus)) { > + for (i = 0; i < CPU_SETSIZE; i++) > + if (odp_cpumask_isset(&odp_global_data.worker_cpus, i)) > + CPU_SET(i, &cpuset); > + } else { > + /* > + * No initial worker cpumask was specified. > + * So allocate worker CPUs from the available CPUs defined > + * by the default OS environment. > + */ > + ret = pthread_getaffinity_np(pthread_self(), > + sizeof(cpu_set_t), &cpuset); > + if (ret != 0) > + ODP_ABORT("failed to read CPU affinity value\n"); > + } Maybe this belongs to global_init and this function would just copy out the already initialized mask. See under. > > odp_cpumask_zero(mask); > > @@ -28,7 +45,7 @@ int odp_cpumask_default_worker(odp_cpumask_t *mask, int > num) > * If no user supplied number or it's too large, then attempt > * to use all CPUs > */ > - if (0 == num || CPU_SETSIZE < num) > + if (0 == num || CPU_COUNT(&cpuset) < num) > num = CPU_COUNT(&cpuset); > > /* build the mask, allocating down from highest numbered CPU */ > @@ -48,10 +65,25 @@ int odp_cpumask_default_worker(odp_cpumask_t *mask, > int num) > > int odp_cpumask_default_control(odp_cpumask_t *mask, int num ODP_UNUSED) > { > + int cpu_count = 0; > + > odp_cpumask_zero(mask); > - /* By default all control threads on CPU 0 */ > - odp_cpumask_set(mask, 0); > - return 1; > + > + /* > + * If the available control cpumask was specified prior to global > init, > + * then allocate control CPUs from that cpumask. > + */ > + cpu_count = odp_cpumask_count(&odp_global_data.control_cpus); > + if (cpu_count) > + odp_cpumask_copy(mask, &odp_global_data.control_cpus); > + > + /* CPU 0 must always be usable for control threads */ > + if (!odp_cpumask_isset(mask, 0)) { > + odp_cpumask_set(mask, 0); > + cpu_count++; > + } If user has passed a mask that has only e.g. CPU 1 set, implementation should return only that and not add CPU 0 into the mask. So, this would be an else branch (by default CPU0, if user didn't pass a mask). > + > + return cpu_count; > } > > int odp_cpumask_all_available(odp_cpumask_t *mask) > diff --git a/platform/linux-generic/odp_init.c b/platform/linux- > generic/odp_init.c > index 6ad3320..38850ce 100644 > --- a/platform/linux-generic/odp_init.c > +++ b/platform/linux-generic/odp_init.c > @@ -23,6 +23,25 @@ int odp_init_global(const odp_init_t *params, > odp_global_data.log_fn = params->log_fn; > if (params->abort_fn != NULL) > odp_global_data.abort_fn = params->abort_fn; > + /* > + * Save the control and worker cpumask contents > + * in a globally accessible data structure > + * so odp_cpumask_default_control(), > + * odp_cpumask_default_worker(), and any > + * isolation support logic may reference them later. > + */ > + if (params->control_cpus && > + odp_cpumask_count(params->control_cpus)) > + odp_cpumask_copy(&odp_global_data.control_cpus, > + params->control_cpus); > + else > + odp_cpumask_zero(&odp_global_data.control_cpus); The check for the count is redundant. Also, I think the mask should be initialized already here - instead of expecting that user will call odp_cpumask_default_xxx(). If user don't call it, other operations may fail later since these mask are empty. /* Sanity check masks */ if (params->control_cpus && params->worker_cpus) if (masks overlap) return -1; if (params->control_cpus) if (odp_cpumask_last(params->control_cpus) > maximum CPU id in the system) return -1; ... if (params->control_cpus) /* copy user defined CPUs */ odp_cpumask_copy(&odp_global_data.control_cpus, params->control_cpus); else /* Use implementation defined defaults */ odp_cpumask_zero(&odp_global_data.control_cpus); ... set default CPUs ... -Petri > + if (params->worker_cpus && > + odp_cpumask_count(params->worker_cpus)) > + odp_cpumask_copy(&odp_global_data.worker_cpus, > + params->worker_cpus); > + else > + odp_cpumask_zero(&odp_global_data.worker_cpus); > } > > if (odp_time_init_global()) { > diff --git a/platform/linux-generic/odp_system_info.c b/platform/linux- > generic/odp_system_info.c > index de28fab..70ebf57 100644 > --- a/platform/linux-generic/odp_system_info.c > +++ b/platform/linux-generic/odp_system_info.c > @@ -8,6 +8,7 @@ > > #include <odp/system_info.h> > #include <odp_internal.h> > +#include <odp/cpumask.h> > #include <odp_debug_internal.h> > #include <odp/align.h> > #include <odp/cpu.h> > @@ -39,19 +40,13 @@ typedef struct { > > > /* > - * Report the number of CPUs in the affinity mask of the main thread > + * Report the number of CPUs available to this ODP application / instance > */ > static int sysconf_cpu_count(void) > { > - cpu_set_t cpuset; > - int ret; > - > - ret = pthread_getaffinity_np(pthread_self(), > - sizeof(cpuset), &cpuset); > - if (ret != 0) > - return 0; > + odp_cpumask_t mask; > > - return CPU_COUNT(&cpuset); > + return odp_cpumask_all_available(&mask); > } > > #if defined __x86_64__ || defined __i386__ || defined __OCTEON__ || \ > -- > 1.9.1 _______________________________________________ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp