svn commit: r267716 - in head/sys: kern sys
Konstantin Belousov
kostikbel at gmail.com
Thu Aug 7 13:46:25 UTC 2014
On Sun, Jun 22, 2014 at 11:32:23AM +0000, Alexander V. Chernikov wrote:
> Author: melifaro
> Date: Sun Jun 22 11:32:23 2014
> New Revision: 267716
> URL: http://svnweb.freebsd.org/changeset/base/267716
>
> Log:
> Permit changing cpu mask for cpu set 1 in presence of drivers
> binding their threads to particular CPU.
>
> Changing ithread cpu mask is now performed by special cpuset_setithread().
> It creates additional cpuset root group on first bind invocation.
>
> No objection: jhb
> Tested by: hiren
> MFC after: 2 weeks
> Sponsored by: Yandex LLC
>
> Modified:
> head/sys/kern/kern_cpuset.c
> head/sys/kern/kern_intr.c
> head/sys/sys/cpuset.h
>
> Modified: head/sys/kern/kern_cpuset.c
> ==============================================================================
> --- head/sys/kern/kern_cpuset.c Sun Jun 22 10:00:33 2014 (r267715)
> +++ head/sys/kern/kern_cpuset.c Sun Jun 22 11:32:23 2014 (r267716)
> @@ -106,7 +106,7 @@ static uma_zone_t cpuset_zone;
> static struct mtx cpuset_lock;
> static struct setlist cpuset_ids;
> static struct unrhdr *cpuset_unr;
> -static struct cpuset *cpuset_zero;
> +static struct cpuset *cpuset_zero, *cpuset_default;
>
> /* Return the size of cpuset_t at the kernel level */
> SYSCTL_INT(_kern_sched, OID_AUTO, cpusetsize, CTLFLAG_RD,
> @@ -716,6 +716,89 @@ out:
> }
>
> /*
> + * Apply new cpumask to the ithread.
> + */
> +int
> +cpuset_setithread(lwpid_t id, u_char cpu)
> +{
> + struct cpuset *nset, *rset;
> + struct cpuset *parent, *old_set;
> + struct thread *td;
> + struct proc *p;
> + cpusetid_t cs_id;
> + cpuset_t mask;
> + int error;
> +
> + nset = uma_zalloc(cpuset_zone, M_WAITOK);
> + rset = uma_zalloc(cpuset_zone, M_WAITOK);
> +
> + CPU_ZERO(&mask);
> + if (cpu == NOCPU)
> + CPU_COPY(cpuset_root, &mask);
> + else
> + CPU_SET(cpu, &mask);
> +
> + error = cpuset_which(CPU_WHICH_TID, id, &p, &td, &old_set);
> + if (((cs_id = alloc_unr(cpuset_unr)) == CPUSET_INVALID) || error != 0)
Why calling alloc_unr() at all if error != 0 ?
> + goto out;
> +
> + thread_lock(td);
> + old_set = td->td_cpuset;
> +
> + if (cpu == NOCPU) {
> + /*
> + * roll back to default set. We're not using cpuset_shadow()
> + * here because we can fail CPU_SUBSET() check. This can happen
> + * if default set does not contain all CPUs.
> + */
> + error = _cpuset_create(nset, cpuset_default, &mask,
> + CPUSET_INVALID);
Why should _cpuset_create() be called under the thread_lock() taken ?
> +
> + goto applyset;
> + }
> +
> + if (old_set->cs_id == 1 || (old_set->cs_id == CPUSET_INVALID &&
> + old_set->cs_parent->cs_id == 1)) {
> + /* Default mask, we need to use new root set */
> + error = _cpuset_create(rset, cpuset_zero,
> + &cpuset_zero->cs_mask, cs_id);
And this one, does the call need thread_lock ?
> + if (error != 0) {
Wouldn't this leak thread_lock() ?
> + PROC_UNLOCK(p);
> + goto out;
> + }
> + rset->cs_flags |= CPU_SET_ROOT;
> + parent = rset;
> + rset = NULL;
> + cs_id = CPUSET_INVALID;
> + } else {
> + /* Assume existing set was already allocated by previous call */
> + parent = td->td_cpuset;
> + old_set = NULL;
> + }
> +
> + error = cpuset_shadow(parent, nset, &mask);
> +applyset:
> + if (error == 0) {
> + td->td_cpuset = nset;
> + sched_affinity(td);
> + nset = NULL;
> + }
> + thread_unlock(td);
> + PROC_UNLOCK(p);
> + if (old_set != NULL)
> + cpuset_rel(old_set);
> +out:
> + if (nset != NULL)
> + uma_zfree(cpuset_zone, nset);
> + if (rset != NULL)
> + uma_zfree(cpuset_zone, rset);
> + if (cs_id != CPUSET_INVALID)
> + free_unr(cpuset_unr, cs_id);
> + return (error);
> +}
> +
> +
> +/*
> * Creates the cpuset for thread0. We make two sets:
> *
> * 0 - The root set which should represent all valid processors in the
> @@ -735,6 +818,7 @@ cpuset_thread0(void)
> cpuset_zone = uma_zcreate("cpuset", sizeof(struct cpuset), NULL, NULL,
> NULL, NULL, UMA_ALIGN_PTR, 0);
> mtx_init(&cpuset_lock, "cpuset", NULL, MTX_SPIN | MTX_RECURSE);
> +
> /*
> * Create the root system set for the whole machine. Doesn't use
> * cpuset_create() due to NULL parent.
> @@ -747,12 +831,15 @@ cpuset_thread0(void)
> set->cs_flags = CPU_SET_ROOT;
> cpuset_zero = set;
> cpuset_root = &set->cs_mask;
> +
> /*
> * Now derive a default, modifiable set from that to give out.
> */
> set = uma_zalloc(cpuset_zone, M_WAITOK);
> error = _cpuset_create(set, cpuset_zero, &cpuset_zero->cs_mask, 1);
> KASSERT(error == 0, ("Error creating default set: %d\n", error));
> + cpuset_default = set;
> +
> /*
> * Initialize the unit allocator. 0 and 1 are allocated above.
> */
>
> Modified: head/sys/kern/kern_intr.c
> ==============================================================================
> --- head/sys/kern/kern_intr.c Sun Jun 22 10:00:33 2014 (r267715)
> +++ head/sys/kern/kern_intr.c Sun Jun 22 11:32:23 2014 (r267716)
> @@ -295,7 +295,6 @@ intr_event_create(struct intr_event **ev
> int
> intr_event_bind(struct intr_event *ie, u_char cpu)
> {
> - cpuset_t mask;
> lwpid_t id;
> int error;
>
> @@ -316,14 +315,9 @@ intr_event_bind(struct intr_event *ie, u
> */
> mtx_lock(&ie->ie_lock);
> if (ie->ie_thread != NULL) {
> - CPU_ZERO(&mask);
> - if (cpu == NOCPU)
> - CPU_COPY(cpuset_root, &mask);
> - else
> - CPU_SET(cpu, &mask);
> id = ie->ie_thread->it_thread->td_tid;
> mtx_unlock(&ie->ie_lock);
> - error = cpuset_setthread(id, &mask);
> + error = cpuset_setithread(id, cpu);
> if (error)
> return (error);
> } else
> @@ -332,14 +326,10 @@ intr_event_bind(struct intr_event *ie, u
> if (error) {
> mtx_lock(&ie->ie_lock);
> if (ie->ie_thread != NULL) {
> - CPU_ZERO(&mask);
> - if (ie->ie_cpu == NOCPU)
> - CPU_COPY(cpuset_root, &mask);
> - else
> - CPU_SET(ie->ie_cpu, &mask);
> + cpu = ie->ie_cpu;
> id = ie->ie_thread->it_thread->td_tid;
> mtx_unlock(&ie->ie_lock);
> - (void)cpuset_setthread(id, &mask);
> + (void)cpuset_setithread(id, cpu);
> } else
> mtx_unlock(&ie->ie_lock);
> return (error);
>
> Modified: head/sys/sys/cpuset.h
> ==============================================================================
> --- head/sys/sys/cpuset.h Sun Jun 22 10:00:33 2014 (r267715)
> +++ head/sys/sys/cpuset.h Sun Jun 22 11:32:23 2014 (r267716)
> @@ -118,6 +118,7 @@ struct cpuset *cpuset_thread0(void);
> struct cpuset *cpuset_ref(struct cpuset *);
> void cpuset_rel(struct cpuset *);
> int cpuset_setthread(lwpid_t id, cpuset_t *);
> +int cpuset_setithread(lwpid_t id, u_char cpu);
> int cpuset_create_root(struct prison *, struct cpuset **);
> int cpuset_setproc_update_set(struct proc *, struct cpuset *);
> char *cpusetobj_strprint(char *, const cpuset_t *);
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.freebsd.org/pipermail/svn-src-all/attachments/20140807/88b87240/attachment.sig>
More information about the svn-src-all
mailing list