Deleted Added
full compact
kern_cpuset.c (180358) kern_cpuset.c (185435)
1/*-
2 * Copyright (c) 2008, Jeffrey Roberson <jeff@freebsd.org>
3 * All rights reserved.
4 *
5 * Copyright (c) 2008 Nokia Corporation
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 15 unchanged lines hidden (view full) ---

24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *
29 */
30
31#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2008, Jeffrey Roberson <jeff@freebsd.org>
3 * All rights reserved.
4 *
5 * Copyright (c) 2008 Nokia Corporation
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 15 unchanged lines hidden (view full) ---

24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *
29 */
30
31#include <sys/cdefs.h>
32__FBSDID("$FreeBSD: head/sys/kern/kern_cpuset.c 180358 2008-07-07 21:32:02Z bz $");
32__FBSDID("$FreeBSD: head/sys/kern/kern_cpuset.c 185435 2008-11-29 14:32:14Z bz $");
33
34#include "opt_ddb.h"
35
36#include <sys/param.h>
37#include <sys/systm.h>
38#include <sys/sysproto.h>
39#include <sys/kernel.h>
40#include <sys/lock.h>

--- 7 unchanged lines hidden (view full) ---

48#include <sys/syscallsubr.h>
49#include <sys/cpuset.h>
50#include <sys/sx.h>
51#include <sys/refcount.h>
52#include <sys/queue.h>
53#include <sys/limits.h>
54#include <sys/bus.h>
55#include <sys/interrupt.h>
33
34#include "opt_ddb.h"
35
36#include <sys/param.h>
37#include <sys/systm.h>
38#include <sys/sysproto.h>
39#include <sys/kernel.h>
40#include <sys/lock.h>

--- 7 unchanged lines hidden (view full) ---

48#include <sys/syscallsubr.h>
49#include <sys/cpuset.h>
50#include <sys/sx.h>
51#include <sys/refcount.h>
52#include <sys/queue.h>
53#include <sys/limits.h>
54#include <sys/bus.h>
55#include <sys/interrupt.h>
56#include <sys/jail.h> /* Must come after sys/proc.h */
56
57#include <vm/uma.h>
58
59#ifdef DDB
60#include <ddb/ddb.h>
61#endif /* DDB */
62
63/*

--- 139 unchanged lines hidden (view full) ---

203 cpuset_rel(set->cs_parent);
204 uma_zfree(cpuset_zone, set);
205}
206
207/*
208 * Find a set based on an id. Returns it with a ref.
209 */
210static struct cpuset *
57
58#include <vm/uma.h>
59
60#ifdef DDB
61#include <ddb/ddb.h>
62#endif /* DDB */
63
64/*

--- 139 unchanged lines hidden (view full) ---

204 cpuset_rel(set->cs_parent);
205 uma_zfree(cpuset_zone, set);
206}
207
208/*
209 * Find a set based on an id. Returns it with a ref.
210 */
211static struct cpuset *
211cpuset_lookup(cpusetid_t setid)
212cpuset_lookup(cpusetid_t setid, struct thread *td)
212{
213 struct cpuset *set;
214
215 if (setid == CPUSET_INVALID)
216 return (NULL);
217 mtx_lock_spin(&cpuset_lock);
218 LIST_FOREACH(set, &cpuset_ids, cs_link)
219 if (set->cs_id == setid)
220 break;
221 if (set)
222 cpuset_ref(set);
223 mtx_unlock_spin(&cpuset_lock);
213{
214 struct cpuset *set;
215
216 if (setid == CPUSET_INVALID)
217 return (NULL);
218 mtx_lock_spin(&cpuset_lock);
219 LIST_FOREACH(set, &cpuset_ids, cs_link)
220 if (set->cs_id == setid)
221 break;
222 if (set)
223 cpuset_ref(set);
224 mtx_unlock_spin(&cpuset_lock);
225
226 KASSERT(td != NULL, ("[%s:%d] td is NULL", __func__, __LINE__));
227 if (set != NULL && jailed(td->td_ucred)) {
228 struct cpuset *rset, *jset;
229 struct prison *pr;
230
231 rset = cpuset_refroot(set);
232
233 pr = td->td_ucred->cr_prison;
234 mtx_lock(&pr->pr_mtx);
235 cpuset_ref(pr->pr_cpuset);
236 jset = pr->pr_cpuset;
237 mtx_unlock(&pr->pr_mtx);
238
239 if (jset->cs_id != rset->cs_id) {
240 cpuset_rel(set);
241 set = NULL;
242 }
243 cpuset_rel(jset);
244 cpuset_rel(rset);
245 }
246
224 return (set);
225}
226
227/*
228 * Create a set in the space provided in 'set' with the provided parameters.
229 * The set is returned with a single ref. May return EDEADLK if the set
230 * will have no valid cpu based on restrictions from the parent.
231 */

--- 175 unchanged lines hidden (view full) ---

407 return (ESRCH);
408 break;
409 case CPU_WHICH_CPUSET:
410 if (id == -1) {
411 thread_lock(curthread);
412 set = cpuset_refbase(curthread->td_cpuset);
413 thread_unlock(curthread);
414 } else
247 return (set);
248}
249
250/*
251 * Create a set in the space provided in 'set' with the provided parameters.
252 * The set is returned with a single ref. May return EDEADLK if the set
253 * will have no valid cpu based on restrictions from the parent.
254 */

--- 175 unchanged lines hidden (view full) ---

430 return (ESRCH);
431 break;
432 case CPU_WHICH_CPUSET:
433 if (id == -1) {
434 thread_lock(curthread);
435 set = cpuset_refbase(curthread->td_cpuset);
436 thread_unlock(curthread);
437 } else
415 set = cpuset_lookup(id);
438 set = cpuset_lookup(id, curthread);
416 if (set) {
417 *setp = set;
418 return (0);
419 }
420 return (ESRCH);
439 if (set) {
440 *setp = set;
441 return (0);
442 }
443 return (ESRCH);
444 case CPU_WHICH_JAIL:
445 {
446 /* Find `set' for prison with given id. */
447 struct prison *pr;
448
449 sx_slock(&allprison_lock);
450 pr = prison_find(id);
451 sx_sunlock(&allprison_lock);
452 if (pr == NULL)
453 return (ESRCH);
454 if (jailed(curthread->td_ucred)) {
455 if (curthread->td_ucred->cr_prison == pr) {
456 cpuset_ref(pr->pr_cpuset);
457 set = pr->pr_cpuset;
458 }
459 } else {
460 cpuset_ref(pr->pr_cpuset);
461 set = pr->pr_cpuset;
462 }
463 mtx_unlock(&pr->pr_mtx);
464 if (set) {
465 *setp = set;
466 return (0);
467 }
468 return (ESRCH);
469 }
421 case CPU_WHICH_IRQ:
422 return (0);
423 default:
424 return (EINVAL);
425 }
426 error = p_cansched(curthread, p);
427 if (error) {
428 PROC_UNLOCK(p);

--- 230 unchanged lines hidden (view full) ---

659 * Initialize the unit allocator. 0 and 1 are allocated above.
660 */
661 cpuset_unr = new_unrhdr(2, INT_MAX, NULL);
662
663 return (set);
664}
665
666/*
470 case CPU_WHICH_IRQ:
471 return (0);
472 default:
473 return (EINVAL);
474 }
475 error = p_cansched(curthread, p);
476 if (error) {
477 PROC_UNLOCK(p);

--- 230 unchanged lines hidden (view full) ---

708 * Initialize the unit allocator. 0 and 1 are allocated above.
709 */
710 cpuset_unr = new_unrhdr(2, INT_MAX, NULL);
711
712 return (set);
713}
714
715/*
716 * Create a cpuset, which would be cpuset_create() but
717 * mark the new 'set' as root.
718 *
719 * We are not going to reparent the td to it. Use cpuset_reparentproc() for that.
720 *
721 * In case of no error, returns the set in *setp locked with a reference.
722 */
723int
724cpuset_create_root(struct thread *td, struct cpuset **setp)
725{
726 struct cpuset *root;
727 struct cpuset *set;
728 int error;
729
730 KASSERT(td != NULL, ("[%s:%d] invalid td", __func__, __LINE__));
731 KASSERT(setp != NULL, ("[%s:%d] invalid setp", __func__, __LINE__));
732
733 thread_lock(td);
734 root = cpuset_refroot(td->td_cpuset);
735 thread_unlock(td);
736
737 error = cpuset_create(setp, td->td_cpuset, &root->cs_mask);
738 cpuset_rel(root);
739 if (error)
740 return (error);
741
742 KASSERT(*setp != NULL, ("[%s:%d] cpuset_create returned invalid data",
743 __func__, __LINE__));
744
745 /* Mark the set as root. */
746 set = *setp;
747 set->cs_flags |= CPU_SET_ROOT;
748
749 return (0);
750}
751
752int
753cpuset_setproc_update_set(struct proc *p, struct cpuset *set)
754{
755 int error;
756
757 KASSERT(p != NULL, ("[%s:%d] invalid proc", __func__, __LINE__));
758 KASSERT(set != NULL, ("[%s:%d] invalid set", __func__, __LINE__));
759
760 cpuset_ref(set);
761 error = cpuset_setproc(p->p_pid, set, NULL);
762 if (error)
763 return (error);
764 cpuset_rel(set);
765 return (0);
766}
767
768/*
667 * This is called once the final set of system cpus is known. Modifies
668 * the root set and all children and mark the root readonly.
669 */
670static void
671cpuset_init(void *arg)
672{
673 cpuset_t mask;
674

--- 48 unchanged lines hidden (view full) ---

723 struct cpuset *set;
724 int error;
725
726 /*
727 * Presently we only support per-process sets.
728 */
729 if (uap->which != CPU_WHICH_PID)
730 return (EINVAL);
769 * This is called once the final set of system cpus is known. Modifies
770 * the root set and all children and mark the root readonly.
771 */
772static void
773cpuset_init(void *arg)
774{
775 cpuset_t mask;
776

--- 48 unchanged lines hidden (view full) ---

825 struct cpuset *set;
826 int error;
827
828 /*
829 * Presently we only support per-process sets.
830 */
831 if (uap->which != CPU_WHICH_PID)
832 return (EINVAL);
731 set = cpuset_lookup(uap->setid);
833 set = cpuset_lookup(uap->setid, td);
732 if (set == NULL)
733 return (ESRCH);
734 error = cpuset_setproc(uap->id, set, NULL);
735 cpuset_rel(set);
736 return (error);
737}
738
739#ifndef _SYS_SYSPROTO_H_

--- 22 unchanged lines hidden (view full) ---

762 case CPU_WHICH_TID:
763 case CPU_WHICH_PID:
764 thread_lock(ttd);
765 set = cpuset_refbase(ttd->td_cpuset);
766 thread_unlock(ttd);
767 PROC_UNLOCK(p);
768 break;
769 case CPU_WHICH_CPUSET:
834 if (set == NULL)
835 return (ESRCH);
836 error = cpuset_setproc(uap->id, set, NULL);
837 cpuset_rel(set);
838 return (error);
839}
840
841#ifndef _SYS_SYSPROTO_H_

--- 22 unchanged lines hidden (view full) ---

864 case CPU_WHICH_TID:
865 case CPU_WHICH_PID:
866 thread_lock(ttd);
867 set = cpuset_refbase(ttd->td_cpuset);
868 thread_unlock(ttd);
869 PROC_UNLOCK(p);
870 break;
871 case CPU_WHICH_CPUSET:
872 case CPU_WHICH_JAIL:
770 break;
771 case CPU_WHICH_IRQ:
772 return (EINVAL);
773 }
774 switch (uap->level) {
775 case CPU_LEVEL_ROOT:
776 nset = cpuset_refroot(set);
777 cpuset_rel(set);

--- 46 unchanged lines hidden (view full) ---

824 switch (uap->which) {
825 case CPU_WHICH_TID:
826 case CPU_WHICH_PID:
827 thread_lock(ttd);
828 set = cpuset_ref(ttd->td_cpuset);
829 thread_unlock(ttd);
830 break;
831 case CPU_WHICH_CPUSET:
873 break;
874 case CPU_WHICH_IRQ:
875 return (EINVAL);
876 }
877 switch (uap->level) {
878 case CPU_LEVEL_ROOT:
879 nset = cpuset_refroot(set);
880 cpuset_rel(set);

--- 46 unchanged lines hidden (view full) ---

927 switch (uap->which) {
928 case CPU_WHICH_TID:
929 case CPU_WHICH_PID:
930 thread_lock(ttd);
931 set = cpuset_ref(ttd->td_cpuset);
932 thread_unlock(ttd);
933 break;
934 case CPU_WHICH_CPUSET:
935 case CPU_WHICH_JAIL:
832 break;
833 case CPU_WHICH_IRQ:
834 error = EINVAL;
835 goto out;
836 }
837 if (uap->level == CPU_LEVEL_ROOT)
838 nset = cpuset_refroot(set);
839 else

--- 11 unchanged lines hidden (view full) ---

851 case CPU_WHICH_PID:
852 FOREACH_THREAD_IN_PROC(p, ttd) {
853 thread_lock(ttd);
854 CPU_OR(mask, &ttd->td_cpuset->cs_mask);
855 thread_unlock(ttd);
856 }
857 break;
858 case CPU_WHICH_CPUSET:
936 break;
937 case CPU_WHICH_IRQ:
938 error = EINVAL;
939 goto out;
940 }
941 if (uap->level == CPU_LEVEL_ROOT)
942 nset = cpuset_refroot(set);
943 else

--- 11 unchanged lines hidden (view full) ---

955 case CPU_WHICH_PID:
956 FOREACH_THREAD_IN_PROC(p, ttd) {
957 thread_lock(ttd);
958 CPU_OR(mask, &ttd->td_cpuset->cs_mask);
959 thread_unlock(ttd);
960 }
961 break;
962 case CPU_WHICH_CPUSET:
963 case CPU_WHICH_JAIL:
859 CPU_COPY(&set->cs_mask, mask);
860 break;
861 case CPU_WHICH_IRQ:
862 error = intr_getaffinity(uap->id, mask);
863 break;
864 }
865 break;
866 default:

--- 64 unchanged lines hidden (view full) ---

931 case CPU_WHICH_TID:
932 case CPU_WHICH_PID:
933 thread_lock(ttd);
934 set = cpuset_ref(ttd->td_cpuset);
935 thread_unlock(ttd);
936 PROC_UNLOCK(p);
937 break;
938 case CPU_WHICH_CPUSET:
964 CPU_COPY(&set->cs_mask, mask);
965 break;
966 case CPU_WHICH_IRQ:
967 error = intr_getaffinity(uap->id, mask);
968 break;
969 }
970 break;
971 default:

--- 64 unchanged lines hidden (view full) ---

1036 case CPU_WHICH_TID:
1037 case CPU_WHICH_PID:
1038 thread_lock(ttd);
1039 set = cpuset_ref(ttd->td_cpuset);
1040 thread_unlock(ttd);
1041 PROC_UNLOCK(p);
1042 break;
1043 case CPU_WHICH_CPUSET:
1044 case CPU_WHICH_JAIL:
939 break;
940 case CPU_WHICH_IRQ:
941 error = EINVAL;
942 goto out;
943 }
944 if (uap->level == CPU_LEVEL_ROOT)
945 nset = cpuset_refroot(set);
946 else

--- 6 unchanged lines hidden (view full) ---

953 switch (uap->which) {
954 case CPU_WHICH_TID:
955 error = cpuset_setthread(uap->id, mask);
956 break;
957 case CPU_WHICH_PID:
958 error = cpuset_setproc(uap->id, NULL, mask);
959 break;
960 case CPU_WHICH_CPUSET:
1045 break;
1046 case CPU_WHICH_IRQ:
1047 error = EINVAL;
1048 goto out;
1049 }
1050 if (uap->level == CPU_LEVEL_ROOT)
1051 nset = cpuset_refroot(set);
1052 else

--- 6 unchanged lines hidden (view full) ---

1059 switch (uap->which) {
1060 case CPU_WHICH_TID:
1061 error = cpuset_setthread(uap->id, mask);
1062 break;
1063 case CPU_WHICH_PID:
1064 error = cpuset_setproc(uap->id, NULL, mask);
1065 break;
1066 case CPU_WHICH_CPUSET:
961 error = cpuset_which(CPU_WHICH_CPUSET, uap->id, &p,
1067 case CPU_WHICH_JAIL:
1068 error = cpuset_which(uap->which, uap->id, &p,
962 &ttd, &set);
963 if (error == 0) {
964 error = cpuset_modify(set, mask);
965 cpuset_rel(set);
966 }
967 break;
968 case CPU_WHICH_IRQ:
969 error = intr_setaffinity(uap->id, mask);

--- 41 unchanged lines hidden ---
1069 &ttd, &set);
1070 if (error == 0) {
1071 error = cpuset_modify(set, mask);
1072 cpuset_rel(set);
1073 }
1074 break;
1075 case CPU_WHICH_IRQ:
1076 error = intr_setaffinity(uap->id, mask);

--- 41 unchanged lines hidden ---