mirror of
https://github.com/freebsd/freebsd-src
synced 2024-10-03 07:04:53 +00:00
Add a new taskqueue setup method that takes a cpuid to pin the
taskqueue worker thread(s) to. For now it isn't a taskqueue/taskthread error to fail to pin to the given cpuid. Thanks to rpaulo@, kib@ and jhb@ for feedback. Tested: * igb(4), with local RSS patches to pin taskqueues. TODO: * ask the doc team for help in documenting the new API call. * add a taskqueue_start_threads_cpuset() method which takes a cpuset_t - but this may require a bunch of surgery to bring cpuset_t into scope.
This commit is contained in:
parent
6fea75b4be
commit
5a6f0eee47
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=266629
|
@ -30,6 +30,7 @@ __FBSDID("$FreeBSD$");
|
|||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/cpuset.h>
|
||||
#include <sys/interrupt.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/kthread.h>
|
||||
|
@ -496,25 +497,19 @@ taskqueue_swi_giant_run(void *dummy)
|
|||
taskqueue_run(taskqueue_swi_giant);
|
||||
}
|
||||
|
||||
int
|
||||
taskqueue_start_threads(struct taskqueue **tqp, int count, int pri,
|
||||
const char *name, ...)
|
||||
static int
|
||||
_taskqueue_start_threads(struct taskqueue **tqp, int count, int pri,
|
||||
cpuset_t *mask, const char *ktname)
|
||||
{
|
||||
va_list ap;
|
||||
struct thread *td;
|
||||
struct taskqueue *tq;
|
||||
int i, error;
|
||||
char ktname[MAXCOMLEN + 1];
|
||||
|
||||
if (count <= 0)
|
||||
return (EINVAL);
|
||||
|
||||
tq = *tqp;
|
||||
|
||||
va_start(ap, name);
|
||||
vsnprintf(ktname, sizeof(ktname), name, ap);
|
||||
va_end(ap);
|
||||
|
||||
tq->tq_threads = malloc(sizeof(struct thread *) * count, M_TASKQUEUE,
|
||||
M_NOWAIT | M_ZERO);
|
||||
if (tq->tq_threads == NULL) {
|
||||
|
@ -542,6 +537,19 @@ taskqueue_start_threads(struct taskqueue **tqp, int count, int pri,
|
|||
if (tq->tq_threads[i] == NULL)
|
||||
continue;
|
||||
td = tq->tq_threads[i];
|
||||
if (mask) {
|
||||
error = cpuset_setthread(curthread->td_tid, mask);
|
||||
/*
|
||||
* Failing to pin is rarely an actual fatal error;
|
||||
* it'll just affect performance.
|
||||
*/
|
||||
if (error)
|
||||
printf("%s: curthread=%llu: can't pin; "
|
||||
"error=%d\n",
|
||||
__func__,
|
||||
(unsigned long long) td->td_tid,
|
||||
error);
|
||||
}
|
||||
thread_lock(td);
|
||||
sched_prio(td, pri);
|
||||
sched_add(td, SRQ_BORING);
|
||||
|
@ -551,6 +559,45 @@ taskqueue_start_threads(struct taskqueue **tqp, int count, int pri,
|
|||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
taskqueue_start_threads(struct taskqueue **tqp, int count, int pri,
|
||||
const char *name, ...)
|
||||
{
|
||||
char ktname[MAXCOMLEN + 1];
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, name);
|
||||
vsnprintf(ktname, sizeof(ktname), name, ap);
|
||||
va_end(ap);
|
||||
|
||||
return (_taskqueue_start_threads(tqp, count, pri, NULL, ktname));
|
||||
}
|
||||
|
||||
int
|
||||
taskqueue_start_threads_pinned(struct taskqueue **tqp, int count, int pri,
|
||||
int cpu_id, const char *name, ...)
|
||||
{
|
||||
char ktname[MAXCOMLEN + 1];
|
||||
va_list ap;
|
||||
cpuset_t mask;
|
||||
|
||||
va_start(ap, name);
|
||||
vsnprintf(ktname, sizeof(ktname), name, ap);
|
||||
va_end(ap);
|
||||
|
||||
/*
|
||||
* In case someone passes in NOCPU, just fall back to the
|
||||
* default behaviour of "don't pin".
|
||||
*/
|
||||
if (cpu_id != NOCPU) {
|
||||
CPU_ZERO(&mask);
|
||||
CPU_SET(cpu_id, &mask);
|
||||
}
|
||||
|
||||
return (_taskqueue_start_threads(tqp, count, pri,
|
||||
cpu_id == NOCPU ? NULL : &mask, ktname));
|
||||
}
|
||||
|
||||
static inline void
|
||||
taskqueue_run_callback(struct taskqueue *tq,
|
||||
enum taskqueue_callback_type cb_type)
|
||||
|
|
|
@ -71,6 +71,10 @@ struct taskqueue *taskqueue_create(const char *name, int mflags,
|
|||
void *context);
|
||||
int taskqueue_start_threads(struct taskqueue **tqp, int count, int pri,
|
||||
const char *name, ...) __printflike(4, 5);
|
||||
int taskqueue_start_threads_pinned(struct taskqueue **tqp, int count,
|
||||
int pri, int cpu_id, const char *name,
|
||||
...) __printflike(5, 6);
|
||||
|
||||
int taskqueue_enqueue(struct taskqueue *queue, struct task *task);
|
||||
int taskqueue_enqueue_timeout(struct taskqueue *queue,
|
||||
struct timeout_task *timeout_task, int ticks);
|
||||
|
|
Loading…
Reference in a new issue