From: Willy Tarreau Date: Wed, 15 Jun 2022 12:19:48 +0000 (+0200) Subject: MEDIUM: task: add and preset a thread ID in the task struct X-Git-Tag: v2.7-dev2~157 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6ef52f44799dde7587037672e20e3ca8183ecfb7;p=thirdparty%2Fhaproxy.git MEDIUM: task: add and preset a thread ID in the task struct The tasks currently rely on a mask but do not have an assigned thread ID, contrary to tasklets. However, in practice they're either running on a single thread or on any thread, so that it will be worth simplifying all this in order to ease the transition to the thread groups. This patch introduces a "tid" field in the task struct, that's either the number of the thread the task is attached to, or a negative value if the task is not bound to a thread, (i.e. its mask is all_threads_mask). The new ID is only set and updated but not used yet. --- diff --git a/include/haproxy/task-t.h b/include/haproxy/task-t.h index f71b1ec45a..ec6aa13334 100644 --- a/include/haproxy/task-t.h +++ b/include/haproxy/task-t.h @@ -112,7 +112,7 @@ struct task { struct eb32_node wq; /* ebtree node used to hold the task in the wait queue */ int expire; /* next expiration date for this task, in ticks */ short nice; /* task prio from -1024 to +1024 */ - /* 16-bit hole here */ + short tid; /* TID where it's allowed to run, <0 if anywhere */ unsigned long thread_mask; /* mask of thread IDs authorized to process the task */ uint64_t call_date; /* date of the last task wakeup or call */ uint64_t lat_time; /* total latency time experienced */ diff --git a/include/haproxy/task.h b/include/haproxy/task.h index 552f08ad56..d5458bfd6f 100644 --- a/include/haproxy/task.h +++ b/include/haproxy/task.h @@ -333,13 +333,23 @@ static inline void task_queue(struct task *task) */ static inline void task_set_affinity(struct task *t, unsigned long thread_mask) { + int thr; + + if (atleast2(thread_mask)) + thr = -1; + else + thr = my_ffsl(thread_mask) - 1; + if (unlikely(task_in_wq(t))) { task_unlink_wq(t); t->thread_mask = thread_mask; + t->tid = thr; task_queue(t); } - else + else { t->thread_mask = thread_mask; + t->tid = thr; + } } /* @@ -533,8 +543,12 @@ static inline struct task *task_init(struct task *t, unsigned long thread_mask) t->rq.node.leaf_p = NULL; t->state = TASK_SLEEPING; t->thread_mask = thread_mask; - if (atleast2(thread_mask)) + if (atleast2(thread_mask)) { t->state |= TASK_SHARED_WQ; + t->tid = -1; + } + else + t->tid = my_ffsl(thread_mask) - 1; t->nice = 0; t->calls = 0; t->call_date = 0; diff --git a/src/hlua.c b/src/hlua.c index dd39397de1..29843f4e7f 100644 --- a/src/hlua.c +++ b/src/hlua.c @@ -8465,6 +8465,9 @@ struct task *hlua_process_task(struct task *task, void *context, unsigned int st if (atleast2(task->thread_mask)) task_set_affinity(task, tid_bit); + if (task->tid < 0) + task->tid = tid; + /* If it is the first call to the task, we must initialize the * execution timeouts. */ diff --git a/src/stream.c b/src/stream.c index 7df2cc6076..867cba8a59 100644 --- a/src/stream.c +++ b/src/stream.c @@ -3284,7 +3284,7 @@ static int stats_dump_full_strm_to_buffer(struct stconn *sc, struct stream *strm } chunk_appendf(&trash, - " task=%p (state=0x%02x nice=%d calls=%u rate=%u exp=%s tmask=0x%lx%s", + " task=%p (state=0x%02x nice=%d calls=%u rate=%u exp=%s tid=%d tmask=0x%lx%s", strm->task, strm->task->state, strm->task->nice, strm->task->calls, read_freq_ctr(&strm->call_rate), @@ -3292,6 +3292,7 @@ static int stats_dump_full_strm_to_buffer(struct stconn *sc, struct stream *strm tick_is_expired(strm->task->expire, now_ms) ? "" : human_time(TICKS_TO_MS(strm->task->expire - now_ms), TICKS_TO_MS(1000)) : "", + strm->task->tid, strm->task->thread_mask, task_in_rq(strm->task) ? ", running" : ""); @@ -3334,12 +3335,13 @@ static int stats_dump_full_strm_to_buffer(struct stconn *sc, struct stream *strm } else if ((tmpctx = sc_appctx(scf)) != NULL) { chunk_appendf(&trash, - " app0=%p st0=%d st1=%d st2=%d applet=%s tmask=0x%lx nice=%d calls=%u rate=%u cpu=%llu lat=%llu\n", + " app0=%p st0=%d st1=%d st2=%d applet=%s tid=%d tmask=0x%lx nice=%d calls=%u rate=%u cpu=%llu lat=%llu\n", tmpctx, tmpctx->st0, tmpctx->st1, tmpctx->_st2, tmpctx->applet->name, + tmpctx->t->tid, tmpctx->t->thread_mask, tmpctx->t->nice, tmpctx->t->calls, read_freq_ctr(&tmpctx->call_rate), (unsigned long long)tmpctx->t->cpu_time, (unsigned long long)tmpctx->t->lat_time); @@ -3373,12 +3375,13 @@ static int stats_dump_full_strm_to_buffer(struct stconn *sc, struct stream *strm } else if ((tmpctx = sc_appctx(scb)) != NULL) { chunk_appendf(&trash, - " app1=%p st0=%d st1=%d st2=%d applet=%s tmask=0x%lx nice=%d calls=%u rate=%u cpu=%llu lat=%llu\n", + " app1=%p st0=%d st1=%d st2=%d applet=%s tid=%d tmask=0x%lx nice=%d calls=%u rate=%u cpu=%llu lat=%llu\n", tmpctx, tmpctx->st0, tmpctx->st1, tmpctx->_st2, tmpctx->applet->name, + tmpctx->t->tid, tmpctx->t->thread_mask, tmpctx->t->nice, tmpctx->t->calls, read_freq_ctr(&tmpctx->call_rate), (unsigned long long)tmpctx->t->cpu_time, (unsigned long long)tmpctx->t->lat_time);