-
Notifications
You must be signed in to change notification settings - Fork 25
Napi #629
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
base: main
Are you sure you want to change the base?
Napi #629
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -24,6 +24,7 @@ | |||||||||||||||||||||||||
| #include <pthread.h> | ||||||||||||||||||||||||||
| #include <sched.h> | ||||||||||||||||||||||||||
| #include <stdatomic.h> | ||||||||||||||||||||||||||
| #include <sys/eventfd.h> | ||||||||||||||||||||||||||
| #include <sys/queue.h> | ||||||||||||||||||||||||||
| #include <unistd.h> | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
|
|
@@ -42,9 +43,16 @@ int worker_create(unsigned cpu_id) { | |||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| worker->cpu_id = cpu_id; | ||||||||||||||||||||||||||
| worker->lcore_id = LCORE_ID_ANY; | ||||||||||||||||||||||||||
| worker->wakeup_fd = -1; | ||||||||||||||||||||||||||
| pthread_mutex_init(&worker->wakeup.lock, NULL); | ||||||||||||||||||||||||||
| pthread_cond_init(&worker->wakeup.cond, NULL); | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| worker->wakeup_fd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); | ||||||||||||||||||||||||||
| if (worker->wakeup_fd < 0) { | ||||||||||||||||||||||||||
| ret = errno; | ||||||||||||||||||||||||||
| goto end; | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| CPU_ZERO(&cpuset); | ||||||||||||||||||||||||||
| CPU_SET(cpu_id, &cpuset); | ||||||||||||||||||||||||||
| pthread_attr_init(&attr); | ||||||||||||||||||||||||||
|
|
@@ -76,6 +84,8 @@ int worker_create(unsigned cpu_id) { | |||||||||||||||||||||||||
| pthread_cancel(worker->thread); | ||||||||||||||||||||||||||
| pthread_cond_destroy(&worker->wakeup.cond); | ||||||||||||||||||||||||||
| pthread_mutex_destroy(&worker->wakeup.lock); | ||||||||||||||||||||||||||
| if (worker->wakeup_fd >= 0) | ||||||||||||||||||||||||||
| close(worker->wakeup_fd); | ||||||||||||||||||||||||||
| rte_free(worker); | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| LOG(ERR, "worker %u start failed: %s", cpu_id, strerror(ret)); | ||||||||||||||||||||||||||
|
|
@@ -97,6 +107,7 @@ int worker_destroy(unsigned cpu_id) { | |||||||||||||||||||||||||
| pthread_join(worker->thread, NULL); | ||||||||||||||||||||||||||
| pthread_cond_destroy(&worker->wakeup.cond); | ||||||||||||||||||||||||||
| pthread_mutex_destroy(&worker->wakeup.lock); | ||||||||||||||||||||||||||
| close(worker->wakeup_fd); | ||||||||||||||||||||||||||
| worker_graph_free(worker); | ||||||||||||||||||||||||||
| vec_free(worker->rxqs); | ||||||||||||||||||||||||||
| vec_free(worker->txqs); | ||||||||||||||||||||||||||
|
|
@@ -115,10 +126,24 @@ void worker_wait_wakeup(struct worker *w) { | |||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| void worker_wakeup(struct worker *w) { | ||||||||||||||||||||||||||
| uint64_t one = 1; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| pthread_mutex_lock(&w->wakeup.lock); | ||||||||||||||||||||||||||
| w->wakeup.set = true; | ||||||||||||||||||||||||||
| pthread_cond_signal(&w->wakeup.cond); | ||||||||||||||||||||||||||
| pthread_mutex_unlock(&w->wakeup.lock); | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| // The condvar above only reaches a worker parked on graph == NULL. A napi | ||||||||||||||||||||||||||
| // worker idle on rte_epoll_wait is woken through the eventfd instead. | ||||||||||||||||||||||||||
| // EAGAIN means a kick is already pending and undrained, which is enough. | ||||||||||||||||||||||||||
| if (write(w->wakeup_fd, &one, sizeof(one)) != sizeof(one) && errno != EAGAIN) | ||||||||||||||||||||||||||
| LOG(ERR, "worker %u wakeup_fd write: %s", w->cpu_id, strerror(errno)); | ||||||||||||||||||||||||||
|
Comment on lines
+139
to
+140
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win Retry interrupted eventfd writes. If Proposed fix- if (write(w->wakeup_fd, &one, sizeof(one)) != sizeof(one) && errno != EAGAIN)
- LOG(ERR, "worker %u wakeup_fd write: %s", w->cpu_id, strerror(errno));
+ ssize_t n;
+
+ do {
+ n = write(w->wakeup_fd, &one, sizeof(one));
+ } while (n < 0 && errno == EINTR);
+
+ if (n < 0 && errno != EAGAIN)
+ LOG(ERR, "worker %u wakeup_fd write: %s", w->cpu_id, strerror(errno));
+ else if (n >= 0 && n != sizeof(one))
+ LOG(ERR, "worker %u wakeup_fd short write", w->cpu_id);📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| void worker_wakeup_all(void) { | ||||||||||||||||||||||||||
| struct worker *worker; | ||||||||||||||||||||||||||
| STAILQ_FOREACH (worker, &workers, next) | ||||||||||||||||||||||||||
| worker_wakeup(worker); | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| unsigned worker_count(void) { | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🩺 Stability & Availability | 🔴 Critical | ⚡ Quick win
Split cleanup by acquired resource state.
Line 53 can jump to
endbefore the worker is inserted or the thread is created, but the error path still runsSTAILQ_REMOVE()andpthread_cancel()on those unacquired resources. Trackinserted/thread_createdflags or use staged cleanup labels before routing earlyeventfd()failures through the shared teardown.🤖 Prompt for AI Agents