Thread (133 messages) 133 messages, 11 authors, 2022-12-16

Re: [dpdk-dev] [PATCH v3 6/9] eal: register non-EAL threads as lcores

From: David Marchand <hidden>
Date: 2020-06-23 07:49:36

Hello Konstantin,

On Mon, Jun 22, 2020 at 5:49 PM Ananyev, Konstantin
[off-list ref] wrote:
quoted
diff --git a/lib/librte_eal/common/eal_common_lcore.c b/lib/librte_eal/common/eal_common_lcore.c
index 86d32a3dd7..7db05428e7 100644
--- a/lib/librte_eal/common/eal_common_lcore.c
+++ b/lib/librte_eal/common/eal_common_lcore.c
@@ -220,3 +221,38 @@ rte_socket_id_by_idx(unsigned int idx)
      }
      return config->numa_nodes[idx];
 }
+
+static rte_spinlock_t lcore_lock = RTE_SPINLOCK_INITIALIZER;
+
+unsigned int
+eal_lcore_non_eal_allocate(void)
+{
+     struct rte_config *cfg = rte_eal_get_configuration();
+     unsigned int lcore_id;
+
+     rte_spinlock_lock(&lcore_lock);
I think it will break current DPDK MP modes.
The problem here - rte_config (and lcore_role[]) is in shared memory,
while the lock is local.
Simplest way probably to move lcore_lock to rte_config.
Even before this series, MP has no protection on lcore placing between
primary and secondary processes.
Personally, I have no use for DPDK MP and marking MP as not supporting
this new feature is tempting for a first phase.
If this is a strong requirement, I can look at it in a second phase.
What do you think?

quoted
+     for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
+             if (cfg->lcore_role[lcore_id] != ROLE_OFF)
+                     continue;
+             cfg->lcore_role[lcore_id] = ROLE_NON_EAL;
+             cfg->lcore_count++;
+             break;
+     }
+     if (lcore_id == RTE_MAX_LCORE)
+             RTE_LOG(DEBUG, EAL, "No lcore available.\n");
+     rte_spinlock_unlock(&lcore_lock);
+     return lcore_id;
+}
+
+void
+eal_lcore_non_eal_release(unsigned int lcore_id)
+{
+     struct rte_config *cfg = rte_eal_get_configuration();
+
+     rte_spinlock_lock(&lcore_lock);
+     if (cfg->lcore_role[lcore_id] == ROLE_NON_EAL) {
+             cfg->lcore_role[lcore_id] = ROLE_OFF;
+             cfg->lcore_count--;
+     }
+     rte_spinlock_unlock(&lcore_lock);
+}
diff --git a/lib/librte_eal/common/eal_common_thread.c b/lib/librte_eal/common/eal_common_thread.c
index a7ae0691bf..1cbddc4b5b 100644
--- a/lib/librte_eal/common/eal_common_thread.c
+++ b/lib/librte_eal/common/eal_common_thread.c
@@ -236,3 +236,36 @@ rte_ctrl_thread_create(pthread_t *thread, const char *name,
      pthread_join(*thread, NULL);
      return -ret;
 }
+
+void
+rte_thread_register(void)
+{
+     unsigned int lcore_id;
+     rte_cpuset_t cpuset;
+
+     /* EAL init flushes all lcores, we can't register before. */
+     assert(internal_config.init_complete == 1);
+     if (pthread_getaffinity_np(pthread_self(), sizeof(cpuset),
+                     &cpuset) != 0)
+             CPU_ZERO(&cpuset);
+     lcore_id = eal_lcore_non_eal_allocate();
+     if (lcore_id >= RTE_MAX_LCORE)
+             lcore_id = LCORE_ID_ANY;
+     rte_thread_init(lcore_id, &cpuset);
So we just setting affinity to the same value, right?
Not a big deal, but might be easier to allow rte_thread_init()
to accept cpuset==NULL (and just don't change thread affinity in that case)
rte_thread_init does not change the thread cpu affinity, it handles
per thread (TLS included) variables initialization.

So do you mean accepting cpuset == NULL and do the getaffinity in this case?
rte_thread_init is EAL private for now.
That saves us some code in this function, but we will call with a !=
NULL cpuset in all other EAL code.


-- 
David Marchand
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help