Date: Tue, 18 Oct 2016 13:55:34 +0000 (UTC) From: Sean Bruno <sbruno@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r307566 - head/sys/kern Message-ID: <201610181355.u9IDtYNh009499@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: sbruno Date: Tue Oct 18 13:55:34 2016 New Revision: 307566 URL: https://svnweb.freebsd.org/changeset/base/307566 Log: Ensure that tasks with a specific cpu set prior to smp starting get re-attached to a thread running on that cpu. ref: https://github.com/NextBSD/NextBSD/commit/fcc20e306bc93ebbbe51f3775d1afb527970a2e9 Submitted by: mmacy@nextbsd.org Modified: head/sys/kern/subr_gtaskqueue.c Modified: head/sys/kern/subr_gtaskqueue.c ============================================================================== --- head/sys/kern/subr_gtaskqueue.c Tue Oct 18 13:39:55 2016 (r307565) +++ head/sys/kern/subr_gtaskqueue.c Tue Oct 18 13:55:34 2016 (r307566) @@ -554,7 +554,7 @@ struct taskq_bind_task { }; static void -taskqgroup_cpu_create(struct taskqgroup *qgroup, int idx) +taskqgroup_cpu_create(struct taskqgroup *qgroup, int idx, int cpu) { struct taskqgroup_cpu *qcpu; @@ -564,7 +564,7 @@ taskqgroup_cpu_create(struct taskqgroup taskqueue_thread_enqueue, &qcpu->tgc_taskq); gtaskqueue_start_threads(&qcpu->tgc_taskq, 1, PI_SOFT, "%s_%d", qgroup->tqg_name, idx); - qcpu->tgc_cpu = idx * qgroup->tqg_stride; + qcpu->tgc_cpu = cpu; } static void @@ -633,8 +633,8 @@ taskqgroup_attach(struct taskqgroup *qgr qgroup->tqg_queue[qid].tgc_cnt++; LIST_INSERT_HEAD(&qgroup->tqg_queue[qid].tgc_tasks, gtask, gt_list); gtask->gt_taskqueue = qgroup->tqg_queue[qid].tgc_taskq; - gtask->gt_cpu = qgroup->tqg_queue[qid].tgc_cpu; if (irq != -1 && smp_started) { + gtask->gt_cpu = qgroup->tqg_queue[qid].tgc_cpu; CPU_ZERO(&mask); CPU_SET(qgroup->tqg_queue[qid].tgc_cpu, &mask); mtx_unlock(&qgroup->tqg_lock); @@ -643,6 +643,32 @@ taskqgroup_attach(struct taskqgroup *qgr mtx_unlock(&qgroup->tqg_lock); } +static void +taskqgroup_attach_deferred(struct taskqgroup *qgroup, struct grouptask *gtask) +{ + cpuset_t mask; + int qid, cpu; + + mtx_lock(&qgroup->tqg_lock); + qid = taskqgroup_find(qgroup, gtask->gt_uniq); + cpu = qgroup->tqg_queue[qid].tgc_cpu; + if (gtask->gt_irq != -1) { + mtx_unlock(&qgroup->tqg_lock); + + CPU_ZERO(&mask); + CPU_SET(cpu, &mask); + intr_setaffinity(gtask->gt_irq, &mask); + + mtx_lock(&qgroup->tqg_lock); + } + qgroup->tqg_queue[qid].tgc_cnt++; + + LIST_INSERT_HEAD(&qgroup->tqg_queue[qid].tgc_tasks, gtask, + gt_list); + gtask->gt_taskqueue = qgroup->tqg_queue[qid].tgc_taskq; + mtx_unlock(&qgroup->tqg_lock); +} + int taskqgroup_attach_cpu(struct taskqgroup *qgroup, struct grouptask *gtask, void *uniq, int cpu, int irq, char *name) @@ -671,13 +697,46 @@ taskqgroup_attach_cpu(struct taskqgroup qgroup->tqg_queue[qid].tgc_cnt++; LIST_INSERT_HEAD(&qgroup->tqg_queue[qid].tgc_tasks, gtask, gt_list); gtask->gt_taskqueue = qgroup->tqg_queue[qid].tgc_taskq; - if (irq != -1 && smp_started) { - CPU_ZERO(&mask); - CPU_SET(qgroup->tqg_queue[qid].tgc_cpu, &mask); - mtx_unlock(&qgroup->tqg_lock); + cpu = qgroup->tqg_queue[qid].tgc_cpu; + mtx_unlock(&qgroup->tqg_lock); + + CPU_ZERO(&mask); + CPU_SET(cpu, &mask); + if (irq != -1 && smp_started) intr_setaffinity(irq, &mask); - } else + return (0); +} + +static int +taskqgroup_attach_cpu_deferred(struct taskqgroup *qgroup, struct grouptask *gtask) +{ + cpuset_t mask; + int i, qid, irq, cpu; + + qid = -1; + irq = gtask->gt_irq; + cpu = gtask->gt_cpu; + MPASS(smp_started); + mtx_lock(&qgroup->tqg_lock); + for (i = 0; i < qgroup->tqg_cnt; i++) + if (qgroup->tqg_queue[i].tgc_cpu == cpu) { + qid = i; + break; + } + if (qid == -1) { mtx_unlock(&qgroup->tqg_lock); + return (EINVAL); + } + qgroup->tqg_queue[qid].tgc_cnt++; + LIST_INSERT_HEAD(&qgroup->tqg_queue[qid].tgc_tasks, gtask, gt_list); + gtask->gt_taskqueue = qgroup->tqg_queue[qid].tgc_taskq; + mtx_unlock(&qgroup->tqg_lock); + + CPU_ZERO(&mask); + CPU_SET(cpu, &mask); + + if (irq != -1) + intr_setaffinity(irq, &mask); return (0); } @@ -741,9 +800,8 @@ static int _taskqgroup_adjust(struct taskqgroup *qgroup, int cnt, int stride) { LIST_HEAD(, grouptask) gtask_head = LIST_HEAD_INITIALIZER(NULL); - cpuset_t mask; struct grouptask *gtask; - int i, k, old_cnt, qid, cpu; + int i, k, old_cnt, old_cpu, cpu; mtx_assert(&qgroup->tqg_lock, MA_OWNED); @@ -758,6 +816,9 @@ _taskqgroup_adjust(struct taskqgroup *qg } qgroup->tqg_adjusting = 1; old_cnt = qgroup->tqg_cnt; + old_cpu = 0; + if (old_cnt < cnt) + old_cpu = qgroup->tqg_queue[old_cnt].tgc_cpu; mtx_unlock(&qgroup->tqg_lock); /* * Set up queue for tasks added before boot. @@ -771,8 +832,13 @@ _taskqgroup_adjust(struct taskqgroup *qg /* * If new taskq threads have been added. */ - for (i = old_cnt; i < cnt; i++) - taskqgroup_cpu_create(qgroup, i); + cpu = old_cpu; + for (i = old_cnt; i < cnt; i++) { + for (k = 0; k < qgroup->tqg_stride; k++) + cpu = CPU_NEXT(cpu); + + taskqgroup_cpu_create(qgroup, i, cpu); + } mtx_lock(&qgroup->tqg_lock); qgroup->tqg_cnt = cnt; qgroup->tqg_stride = stride; @@ -788,39 +854,15 @@ _taskqgroup_adjust(struct taskqgroup *qg } } + mtx_unlock(&qgroup->tqg_lock); + while ((gtask = LIST_FIRST(>ask_head))) { LIST_REMOVE(gtask, gt_list); if (gtask->gt_cpu == -1) - qid = taskqgroup_find(qgroup, gtask->gt_uniq); - else { - for (i = 0; i < qgroup->tqg_cnt; i++) - if (qgroup->tqg_queue[i].tgc_cpu == gtask->gt_cpu) { - qid = i; - break; - } - } - qgroup->tqg_queue[qid].tgc_cnt++; - LIST_INSERT_HEAD(&qgroup->tqg_queue[qid].tgc_tasks, gtask, - gt_list); - gtask->gt_taskqueue = qgroup->tqg_queue[qid].tgc_taskq; - } - /* - * Set new CPU and IRQ affinity - */ - cpu = CPU_FIRST(); - for (i = 0; i < cnt; i++) { - qgroup->tqg_queue[i].tgc_cpu = cpu; - for (k = 0; k < qgroup->tqg_stride; k++) - cpu = CPU_NEXT(cpu); - CPU_ZERO(&mask); - CPU_SET(qgroup->tqg_queue[i].tgc_cpu, &mask); - LIST_FOREACH(gtask, &qgroup->tqg_queue[i].tgc_tasks, gt_list) { - if (gtask->gt_irq == -1) - continue; - intr_setaffinity(gtask->gt_irq, &mask); - } + taskqgroup_attach_deferred(qgroup, gtask); + else if (taskqgroup_attach_cpu_deferred(qgroup, gtask)) + taskqgroup_attach_deferred(qgroup, gtask); } - mtx_unlock(&qgroup->tqg_lock); /* * If taskq thread count has been reduced. @@ -837,12 +879,12 @@ _taskqgroup_adjust(struct taskqgroup *qg } int -taskqgroup_adjust(struct taskqgroup *qgroup, int cpu, int stride) +taskqgroup_adjust(struct taskqgroup *qgroup, int cnt, int stride) { int error; mtx_lock(&qgroup->tqg_lock); - error = _taskqgroup_adjust(qgroup, cpu, stride); + error = _taskqgroup_adjust(qgroup, cnt, stride); mtx_unlock(&qgroup->tqg_lock); return (error);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201610181355.u9IDtYNh009499>