usr/src/uts/common/syscall/pset.c
author <gerald.jelinek@sun.com>
Tue, 25 May 2010 16:50:45 -0600
changeset 12494 15439b11d535
parent 10089 3b42b78e6a26
permissions -rw-r--r--
PSARC/2010/181 PRIV_SYS_RES_BIND privilege 6953849 need ability to bind to processor sets from within a zone
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     1
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     2
 * CDDL HEADER START
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     3
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     4
 * The contents of this file are subject to the terms of the
2308
a86e1db407c3 6298715 Memory allocation in pset_getloadavg not needed
fr157268
parents: 0
diff changeset
     5
 * Common Development and Distribution License (the "License").
a86e1db407c3 6298715 Memory allocation in pset_getloadavg not needed
fr157268
parents: 0
diff changeset
     6
 * You may not use this file except in compliance with the License.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     7
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     8
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     9
 * or http://www.opensolaris.org/os/licensing.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    10
 * See the License for the specific language governing permissions
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    11
 * and limitations under the License.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    12
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    13
 * When distributing Covered Code, include this CDDL HEADER in each
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    14
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    15
 * If applicable, add the following below this CDDL HEADER, with the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    16
 * fields enclosed by brackets "[]" replaced with your own identifying
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    17
 * information: Portions Copyright [yyyy] [name of copyright owner]
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    18
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    19
 * CDDL HEADER END
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    20
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    21
/*
12494
15439b11d535 PSARC/2010/181 PRIV_SYS_RES_BIND privilege
<gerald.jelinek@sun.com>
parents: 10089
diff changeset
    22
 * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    23
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    24
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    25
#include <sys/types.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    26
#include <sys/systm.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    27
#include <sys/cmn_err.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    28
#include <sys/cpuvar.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    29
#include <sys/thread.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    30
#include <sys/disp.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    31
#include <sys/kmem.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    32
#include <sys/debug.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    33
#include <sys/sysmacros.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    34
#include <sys/cpupart.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    35
#include <sys/pset.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    36
#include <sys/modctl.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    37
#include <sys/syscall.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    38
#include <sys/task.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    39
#include <sys/loadavg.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    40
#include <sys/fss.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    41
#include <sys/pool.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    42
#include <sys/pool_pset.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    43
#include <sys/policy.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    44
#include <sys/zone.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    45
#include <sys/contract/process_impl.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    46
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    47
static int	pset(int, long, long, long, long);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    48
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    49
static struct sysent pset_sysent = {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    50
	5,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    51
	SE_ARGC | SE_NOUNLOAD,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    52
	(int (*)())pset,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    53
};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    54
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    55
static struct modlsys modlsys = {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    56
	&mod_syscallops, "processor sets", &pset_sysent
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    57
};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    58
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    59
#ifdef _SYSCALL32_IMPL
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    60
static struct modlsys modlsys32 = {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    61
	&mod_syscallops32, "32-bit pset(2) syscall", &pset_sysent
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    62
};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    63
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    64
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    65
static struct modlinkage modlinkage = {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    66
	MODREV_1,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    67
	&modlsys,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    68
#ifdef _SYSCALL32_IMPL
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    69
	&modlsys32,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    70
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    71
	NULL
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    72
};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    73
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    74
#define	PSET_BADATTR(attr)	((~PSET_NOESCAPE) & (attr))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    75
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    76
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    77
_init(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    78
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    79
	return (mod_install(&modlinkage));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    80
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    81
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    82
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    83
_info(struct modinfo *modinfop)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    84
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    85
	return (mod_info(&modlinkage, modinfop));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    86
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    87
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    88
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    89
pset_create(psetid_t *psetp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    90
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    91
	psetid_t newpset;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    92
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    93
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    94
	if (secpolicy_pset(CRED()) != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    95
		return (set_errno(EPERM));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    96
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    97
	pool_lock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    98
	if (pool_state == POOL_ENABLED) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    99
		pool_unlock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   100
		return (set_errno(ENOTSUP));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   101
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   102
	error = cpupart_create(&newpset);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   103
	if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   104
		pool_unlock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   105
		return (set_errno(error));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   106
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   107
	if (copyout(&newpset, psetp, sizeof (psetid_t)) != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   108
		(void) cpupart_destroy(newpset);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   109
		pool_unlock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   110
		return (set_errno(EFAULT));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   111
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   112
	pool_unlock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   113
	return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   114
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   115
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   116
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   117
pset_destroy(psetid_t pset)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   118
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   119
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   120
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   121
	if (secpolicy_pset(CRED()) != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   122
		return (set_errno(EPERM));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   123
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   124
	pool_lock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   125
	if (pool_state == POOL_ENABLED) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   126
		pool_unlock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   127
		return (set_errno(ENOTSUP));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   128
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   129
	error = cpupart_destroy(pset);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   130
	pool_unlock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   131
	if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   132
		return (set_errno(error));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   133
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   134
		return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   135
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   136
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   137
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   138
pset_assign(psetid_t pset, processorid_t cpuid, psetid_t *opset, int forced)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   139
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   140
	psetid_t oldpset;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   141
	int	error = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   142
	cpu_t	*cp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   143
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   144
	if (pset != PS_QUERY && secpolicy_pset(CRED()) != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   145
		return (set_errno(EPERM));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   146
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   147
	pool_lock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   148
	if (pset != PS_QUERY && pool_state == POOL_ENABLED) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   149
		pool_unlock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   150
		return (set_errno(ENOTSUP));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   151
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   152
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   153
	mutex_enter(&cpu_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   154
	if ((cp = cpu_get(cpuid)) == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   155
		mutex_exit(&cpu_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   156
		pool_unlock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   157
		return (set_errno(EINVAL));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   158
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   159
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   160
	oldpset = cpupart_query_cpu(cp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   161
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   162
	if (pset != PS_QUERY)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   163
		error = cpupart_attach_cpu(pset, cp, forced);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   164
	mutex_exit(&cpu_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   165
	pool_unlock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   166
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   167
	if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   168
		return (set_errno(error));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   169
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   170
	if (opset != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   171
		if (copyout(&oldpset, opset, sizeof (psetid_t)) != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   172
			return (set_errno(EFAULT));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   173
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   174
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   175
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   176
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   177
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   178
pset_info(psetid_t pset, int *typep, uint_t *numcpusp,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   179
    processorid_t *cpulistp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   180
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   181
	int pset_type;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   182
	uint_t user_ncpus = 0, real_ncpus, copy_ncpus;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   183
	processorid_t *pset_cpus = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   184
	int error = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   185
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   186
	if (numcpusp != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   187
		if (copyin(numcpusp, &user_ncpus, sizeof (uint_t)) != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   188
			return (set_errno(EFAULT));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   189
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   190
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   191
	if (user_ncpus > max_ncpus)	/* sanity check */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   192
		user_ncpus = max_ncpus;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   193
	if (user_ncpus != 0 && cpulistp != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   194
		pset_cpus = kmem_alloc(sizeof (processorid_t) * user_ncpus,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   195
		    KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   196
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   197
	real_ncpus = user_ncpus;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   198
	if ((error = cpupart_get_cpus(&pset, pset_cpus, &real_ncpus)) != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   199
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   200
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   201
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   202
	 * Now copyout the information about this processor set.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   203
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   204
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   205
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   206
	 * Get number of cpus to copy back.  If the user didn't pass in
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   207
	 * a big enough buffer, only copy back as many cpus as fits in
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   208
	 * the buffer but copy back the real number of cpus.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   209
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   210
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   211
	if (user_ncpus != 0 && cpulistp != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   212
		copy_ncpus = MIN(real_ncpus, user_ncpus);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   213
		if (copyout(pset_cpus, cpulistp,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   214
		    sizeof (processorid_t) * copy_ncpus) != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   215
			error = EFAULT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   216
			goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   217
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   218
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   219
	if (pset_cpus != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   220
		kmem_free(pset_cpus, sizeof (processorid_t) * user_ncpus);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   221
	if (typep != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   222
		if (pset == PS_NONE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   223
			pset_type = PS_NONE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   224
		else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   225
			pset_type = PS_PRIVATE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   226
		if (copyout(&pset_type, typep, sizeof (int)) != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   227
			return (set_errno(EFAULT));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   228
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   229
	if (numcpusp != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   230
		if (copyout(&real_ncpus, numcpusp, sizeof (uint_t)) != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   231
			return (set_errno(EFAULT));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   232
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   233
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   234
out:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   235
	if (pset_cpus != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   236
		kmem_free(pset_cpus, sizeof (processorid_t) * user_ncpus);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   237
	return (set_errno(error));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   238
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   239
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   240
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   241
pset_bind_thread(kthread_t *tp, psetid_t pset, psetid_t *oldpset, void *projbuf,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   242
    void *zonebuf)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   243
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   244
	int error = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   245
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   246
	ASSERT(pool_lock_held());
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   247
	ASSERT(MUTEX_HELD(&cpu_lock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   248
	ASSERT(MUTEX_HELD(&ttoproc(tp)->p_lock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   249
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   250
	*oldpset = tp->t_bind_pset;
6298
060278005c21 PSARC 2008/138 Soft CPU and processor set bindings
akolb
parents: 3247
diff changeset
   251
060278005c21 PSARC 2008/138 Soft CPU and processor set bindings
akolb
parents: 3247
diff changeset
   252
	switch (pset) {
060278005c21 PSARC 2008/138 Soft CPU and processor set bindings
akolb
parents: 3247
diff changeset
   253
	case PS_SOFT:
060278005c21 PSARC 2008/138 Soft CPU and processor set bindings
akolb
parents: 3247
diff changeset
   254
		TB_PSET_SOFT_SET(tp);
060278005c21 PSARC 2008/138 Soft CPU and processor set bindings
akolb
parents: 3247
diff changeset
   255
		break;
060278005c21 PSARC 2008/138 Soft CPU and processor set bindings
akolb
parents: 3247
diff changeset
   256
060278005c21 PSARC 2008/138 Soft CPU and processor set bindings
akolb
parents: 3247
diff changeset
   257
	case PS_HARD:
060278005c21 PSARC 2008/138 Soft CPU and processor set bindings
akolb
parents: 3247
diff changeset
   258
		TB_PSET_HARD_SET(tp);
060278005c21 PSARC 2008/138 Soft CPU and processor set bindings
akolb
parents: 3247
diff changeset
   259
		break;
060278005c21 PSARC 2008/138 Soft CPU and processor set bindings
akolb
parents: 3247
diff changeset
   260
060278005c21 PSARC 2008/138 Soft CPU and processor set bindings
akolb
parents: 3247
diff changeset
   261
	case PS_QUERY:
060278005c21 PSARC 2008/138 Soft CPU and processor set bindings
akolb
parents: 3247
diff changeset
   262
		break;
060278005c21 PSARC 2008/138 Soft CPU and processor set bindings
akolb
parents: 3247
diff changeset
   263
060278005c21 PSARC 2008/138 Soft CPU and processor set bindings
akolb
parents: 3247
diff changeset
   264
	case PS_QUERY_TYPE:
060278005c21 PSARC 2008/138 Soft CPU and processor set bindings
akolb
parents: 3247
diff changeset
   265
		*oldpset = TB_PSET_IS_SOFT(tp) ? PS_SOFT : PS_HARD;
060278005c21 PSARC 2008/138 Soft CPU and processor set bindings
akolb
parents: 3247
diff changeset
   266
		break;
060278005c21 PSARC 2008/138 Soft CPU and processor set bindings
akolb
parents: 3247
diff changeset
   267
060278005c21 PSARC 2008/138 Soft CPU and processor set bindings
akolb
parents: 3247
diff changeset
   268
	default:
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   269
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   270
		 * Must have the same UID as the target process or
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   271
		 * have PRIV_PROC_OWNER privilege.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   272
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   273
		if (!hasprocperm(tp->t_cred, CRED()))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   274
			return (EPERM);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   275
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   276
		 * Unbinding of an unbound thread should always succeed.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   277
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   278
		if (*oldpset == PS_NONE && pset == PS_NONE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   279
			return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   280
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   281
		 * Only privileged processes can move threads from psets with
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   282
		 * PSET_NOESCAPE attribute.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   283
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   284
		if ((tp->t_cpupart->cp_attr & PSET_NOESCAPE) &&
12494
15439b11d535 PSARC/2010/181 PRIV_SYS_RES_BIND privilege
<gerald.jelinek@sun.com>
parents: 10089
diff changeset
   285
		    secpolicy_pbind(CRED()) != 0)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   286
			return (EPERM);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   287
		if ((error = cpupart_bind_thread(tp, pset, 0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   288
		    projbuf, zonebuf)) == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   289
			tp->t_bind_pset = pset;
6298
060278005c21 PSARC 2008/138 Soft CPU and processor set bindings
akolb
parents: 3247
diff changeset
   290
060278005c21 PSARC 2008/138 Soft CPU and processor set bindings
akolb
parents: 3247
diff changeset
   291
		break;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   292
	}
6298
060278005c21 PSARC 2008/138 Soft CPU and processor set bindings
akolb
parents: 3247
diff changeset
   293
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   294
	return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   295
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   296
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   297
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   298
pset_bind_process(proc_t *pp, psetid_t pset, psetid_t *oldpset, void *projbuf,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   299
    void *zonebuf)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   300
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   301
	int error = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   302
	kthread_t *tp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   303
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   304
	/* skip kernel processes */
6298
060278005c21 PSARC 2008/138 Soft CPU and processor set bindings
akolb
parents: 3247
diff changeset
   305
	if ((pset != PS_QUERY) && pp->p_flag & SSYS) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   306
		*oldpset = PS_NONE;
9150
74da91783a73 6618447 processor_bind(2) returned EPERM when binding bind an active non-global zone to a processor.
Gangadhar Mylapuram <Gangadhar.M@Sun.COM>
parents: 6298
diff changeset
   307
		return (ENOTSUP);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   308
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   309
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   310
	mutex_enter(&pp->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   311
	tp = pp->p_tlist;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   312
	if (tp != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   313
		do {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   314
			int rval;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   315
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   316
			rval = pset_bind_thread(tp, pset, oldpset, projbuf,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   317
			    zonebuf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   318
			if (error == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   319
				error = rval;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   320
		} while ((tp = tp->t_forw) != pp->p_tlist);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   321
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   322
		error = ESRCH;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   323
	mutex_exit(&pp->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   324
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   325
	return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   326
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   327
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   328
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   329
pset_bind_task(task_t *tk, psetid_t pset, psetid_t *oldpset, void *projbuf,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   330
    void *zonebuf)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   331
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   332
	int error = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   333
	proc_t *pp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   334
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   335
	ASSERT(MUTEX_HELD(&pidlock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   336
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   337
	if ((pp = tk->tk_memb_list) == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   338
		return (ESRCH);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   339
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   340
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   341
	do {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   342
		int rval;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   343
9150
74da91783a73 6618447 processor_bind(2) returned EPERM when binding bind an active non-global zone to a processor.
Gangadhar Mylapuram <Gangadhar.M@Sun.COM>
parents: 6298
diff changeset
   344
		if (!(pp->p_flag & SSYS)) {
74da91783a73 6618447 processor_bind(2) returned EPERM when binding bind an active non-global zone to a processor.
Gangadhar Mylapuram <Gangadhar.M@Sun.COM>
parents: 6298
diff changeset
   345
			rval = pset_bind_process(pp, pset, oldpset, projbuf,
74da91783a73 6618447 processor_bind(2) returned EPERM when binding bind an active non-global zone to a processor.
Gangadhar Mylapuram <Gangadhar.M@Sun.COM>
parents: 6298
diff changeset
   346
			    zonebuf);
74da91783a73 6618447 processor_bind(2) returned EPERM when binding bind an active non-global zone to a processor.
Gangadhar Mylapuram <Gangadhar.M@Sun.COM>
parents: 6298
diff changeset
   347
			if (error == 0)
74da91783a73 6618447 processor_bind(2) returned EPERM when binding bind an active non-global zone to a processor.
Gangadhar Mylapuram <Gangadhar.M@Sun.COM>
parents: 6298
diff changeset
   348
				error = rval;
74da91783a73 6618447 processor_bind(2) returned EPERM when binding bind an active non-global zone to a processor.
Gangadhar Mylapuram <Gangadhar.M@Sun.COM>
parents: 6298
diff changeset
   349
		}
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   350
	} while ((pp = pp->p_tasknext) != tk->tk_memb_list);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   351
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   352
	return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   353
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   354
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   355
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   356
pset_bind_project(kproject_t *kpj, psetid_t pset, psetid_t *oldpset,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   357
    void *projbuf, void *zonebuf)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   358
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   359
	int error = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   360
	proc_t *pp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   361
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   362
	ASSERT(MUTEX_HELD(&pidlock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   363
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   364
	for (pp = practive; pp != NULL; pp = pp->p_next) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   365
		if (pp->p_tlist == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   366
			continue;
9150
74da91783a73 6618447 processor_bind(2) returned EPERM when binding bind an active non-global zone to a processor.
Gangadhar Mylapuram <Gangadhar.M@Sun.COM>
parents: 6298
diff changeset
   367
		if (pp->p_task->tk_proj == kpj && !(pp->p_flag & SSYS)) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   368
			int rval;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   369
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   370
			rval = pset_bind_process(pp, pset, oldpset, projbuf,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   371
			    zonebuf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   372
			if (error == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   373
				error = rval;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   374
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   375
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   376
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   377
	return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   378
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   379
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   380
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   381
pset_bind_zone(zone_t *zptr, psetid_t pset, psetid_t *oldpset, void *projbuf,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   382
    void *zonebuf)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   383
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   384
	int error = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   385
	proc_t *pp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   386
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   387
	ASSERT(MUTEX_HELD(&pidlock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   388
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   389
	for (pp = practive; pp != NULL; pp = pp->p_next) {
9150
74da91783a73 6618447 processor_bind(2) returned EPERM when binding bind an active non-global zone to a processor.
Gangadhar Mylapuram <Gangadhar.M@Sun.COM>
parents: 6298
diff changeset
   390
		if (pp->p_zone == zptr && !(pp->p_flag & SSYS)) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   391
			int rval;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   392
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   393
			rval = pset_bind_process(pp, pset, oldpset, projbuf,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   394
			    zonebuf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   395
			if (error == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   396
				error = rval;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   397
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   398
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   399
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   400
	return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   401
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   402
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   403
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   404
 * Unbind all threads from the specified processor set, or from all
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   405
 * processor sets.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   406
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   407
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   408
pset_unbind(psetid_t pset, void *projbuf, void *zonebuf, idtype_t idtype)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   409
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   410
	psetid_t olbind;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   411
	kthread_t *tp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   412
	int error = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   413
	int rval;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   414
	proc_t *pp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   415
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   416
	ASSERT(MUTEX_HELD(&cpu_lock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   417
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   418
	if (idtype == P_PSETID && cpupart_find(pset) == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   419
		return (EINVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   420
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   421
	mutex_enter(&pidlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   422
	for (pp = practive; pp != NULL; pp = pp->p_next) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   423
		mutex_enter(&pp->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   424
		tp = pp->p_tlist;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   425
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   426
		 * Skip zombies and kernel processes, and processes in
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   427
		 * other zones, if called from a non-global zone.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   428
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   429
		if (tp == NULL || (pp->p_flag & SSYS) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   430
		    !HASZONEACCESS(curproc, pp->p_zone->zone_id)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   431
			mutex_exit(&pp->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   432
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   433
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   434
		do {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   435
			if ((idtype == P_PSETID && tp->t_bind_pset != pset) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   436
			    (idtype == P_ALL && tp->t_bind_pset == PS_NONE))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   437
				continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   438
			rval = pset_bind_thread(tp, PS_NONE, &olbind,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   439
			    projbuf, zonebuf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   440
			if (error == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   441
				error = rval;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   442
		} while ((tp = tp->t_forw) != pp->p_tlist);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   443
		mutex_exit(&pp->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   444
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   445
	mutex_exit(&pidlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   446
	return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   447
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   448
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   449
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   450
pset_bind_contract(cont_process_t *ctp, psetid_t pset, psetid_t *oldpset,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   451
    void *projbuf, void *zonebuf)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   452
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   453
	int error = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   454
	proc_t *pp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   455
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   456
	ASSERT(MUTEX_HELD(&pidlock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   457
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   458
	for (pp = practive; pp != NULL; pp = pp->p_next) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   459
		if (pp->p_ct_process == ctp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   460
			int rval;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   461
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   462
			rval = pset_bind_process(pp, pset, oldpset, projbuf,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   463
			    zonebuf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   464
			if (error == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   465
				error = rval;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   466
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   467
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   468
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   469
	return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   470
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   471
10089
3b42b78e6a26 6757037 Zone-spawned LWP needs to be able to run on a processor set
Surya Prakki <Surya.Prakki@Sun.COM>
parents: 9150
diff changeset
   472
/*
3b42b78e6a26 6757037 Zone-spawned LWP needs to be able to run on a processor set
Surya Prakki <Surya.Prakki@Sun.COM>
parents: 9150
diff changeset
   473
 * Bind the lwp:id of process:pid to processor set: pset
3b42b78e6a26 6757037 Zone-spawned LWP needs to be able to run on a processor set
Surya Prakki <Surya.Prakki@Sun.COM>
parents: 9150
diff changeset
   474
 */
3b42b78e6a26 6757037 Zone-spawned LWP needs to be able to run on a processor set
Surya Prakki <Surya.Prakki@Sun.COM>
parents: 9150
diff changeset
   475
static int
3b42b78e6a26 6757037 Zone-spawned LWP needs to be able to run on a processor set
Surya Prakki <Surya.Prakki@Sun.COM>
parents: 9150
diff changeset
   476
pset_bind_lwp(psetid_t pset, id_t id, pid_t pid, psetid_t *opset)
3b42b78e6a26 6757037 Zone-spawned LWP needs to be able to run on a processor set
Surya Prakki <Surya.Prakki@Sun.COM>
parents: 9150
diff changeset
   477
{
3b42b78e6a26 6757037 Zone-spawned LWP needs to be able to run on a processor set
Surya Prakki <Surya.Prakki@Sun.COM>
parents: 9150
diff changeset
   478
	kthread_t	*tp;
3b42b78e6a26 6757037 Zone-spawned LWP needs to be able to run on a processor set
Surya Prakki <Surya.Prakki@Sun.COM>
parents: 9150
diff changeset
   479
	proc_t		*pp;
3b42b78e6a26 6757037 Zone-spawned LWP needs to be able to run on a processor set
Surya Prakki <Surya.Prakki@Sun.COM>
parents: 9150
diff changeset
   480
	psetid_t	oldpset;
3b42b78e6a26 6757037 Zone-spawned LWP needs to be able to run on a processor set
Surya Prakki <Surya.Prakki@Sun.COM>
parents: 9150
diff changeset
   481
	void		*projbuf, *zonebuf;
3b42b78e6a26 6757037 Zone-spawned LWP needs to be able to run on a processor set
Surya Prakki <Surya.Prakki@Sun.COM>
parents: 9150
diff changeset
   482
	int		error = 0;
3b42b78e6a26 6757037 Zone-spawned LWP needs to be able to run on a processor set
Surya Prakki <Surya.Prakki@Sun.COM>
parents: 9150
diff changeset
   483
3b42b78e6a26 6757037 Zone-spawned LWP needs to be able to run on a processor set
Surya Prakki <Surya.Prakki@Sun.COM>
parents: 9150
diff changeset
   484
	pool_lock();
3b42b78e6a26 6757037 Zone-spawned LWP needs to be able to run on a processor set
Surya Prakki <Surya.Prakki@Sun.COM>
parents: 9150
diff changeset
   485
	mutex_enter(&cpu_lock);
3b42b78e6a26 6757037 Zone-spawned LWP needs to be able to run on a processor set
Surya Prakki <Surya.Prakki@Sun.COM>
parents: 9150
diff changeset
   486
	projbuf = fss_allocbuf(FSS_NPROJ_BUF, FSS_ALLOC_PROJ);
3b42b78e6a26 6757037 Zone-spawned LWP needs to be able to run on a processor set
Surya Prakki <Surya.Prakki@Sun.COM>
parents: 9150
diff changeset
   487
	zonebuf = fss_allocbuf(FSS_NPROJ_BUF, FSS_ALLOC_ZONE);
3b42b78e6a26 6757037 Zone-spawned LWP needs to be able to run on a processor set
Surya Prakki <Surya.Prakki@Sun.COM>
parents: 9150
diff changeset
   488
3b42b78e6a26 6757037 Zone-spawned LWP needs to be able to run on a processor set
Surya Prakki <Surya.Prakki@Sun.COM>
parents: 9150
diff changeset
   489
	mutex_enter(&pidlock);
3b42b78e6a26 6757037 Zone-spawned LWP needs to be able to run on a processor set
Surya Prakki <Surya.Prakki@Sun.COM>
parents: 9150
diff changeset
   490
	if ((pid == P_MYID && id == P_MYID) ||
3b42b78e6a26 6757037 Zone-spawned LWP needs to be able to run on a processor set
Surya Prakki <Surya.Prakki@Sun.COM>
parents: 9150
diff changeset
   491
	    (pid == curproc->p_pid && id == P_MYID)) {
3b42b78e6a26 6757037 Zone-spawned LWP needs to be able to run on a processor set
Surya Prakki <Surya.Prakki@Sun.COM>
parents: 9150
diff changeset
   492
		pp = curproc;
3b42b78e6a26 6757037 Zone-spawned LWP needs to be able to run on a processor set
Surya Prakki <Surya.Prakki@Sun.COM>
parents: 9150
diff changeset
   493
		tp = curthread;
3b42b78e6a26 6757037 Zone-spawned LWP needs to be able to run on a processor set
Surya Prakki <Surya.Prakki@Sun.COM>
parents: 9150
diff changeset
   494
		mutex_enter(&pp->p_lock);
3b42b78e6a26 6757037 Zone-spawned LWP needs to be able to run on a processor set
Surya Prakki <Surya.Prakki@Sun.COM>
parents: 9150
diff changeset
   495
	} else {
3b42b78e6a26 6757037 Zone-spawned LWP needs to be able to run on a processor set
Surya Prakki <Surya.Prakki@Sun.COM>
parents: 9150
diff changeset
   496
		if (pid == P_MYID) {
3b42b78e6a26 6757037 Zone-spawned LWP needs to be able to run on a processor set
Surya Prakki <Surya.Prakki@Sun.COM>
parents: 9150
diff changeset
   497
			pp = curproc;
3b42b78e6a26 6757037 Zone-spawned LWP needs to be able to run on a processor set
Surya Prakki <Surya.Prakki@Sun.COM>
parents: 9150
diff changeset
   498
		} else if ((pp = prfind(pid)) == NULL) {
3b42b78e6a26 6757037 Zone-spawned LWP needs to be able to run on a processor set
Surya Prakki <Surya.Prakki@Sun.COM>
parents: 9150
diff changeset
   499
			error = ESRCH;
3b42b78e6a26 6757037 Zone-spawned LWP needs to be able to run on a processor set
Surya Prakki <Surya.Prakki@Sun.COM>
parents: 9150
diff changeset
   500
			goto err;
3b42b78e6a26 6757037 Zone-spawned LWP needs to be able to run on a processor set
Surya Prakki <Surya.Prakki@Sun.COM>
parents: 9150
diff changeset
   501
		}
3b42b78e6a26 6757037 Zone-spawned LWP needs to be able to run on a processor set
Surya Prakki <Surya.Prakki@Sun.COM>
parents: 9150
diff changeset
   502
		if (pp != curproc && id == P_MYID) {
3b42b78e6a26 6757037 Zone-spawned LWP needs to be able to run on a processor set
Surya Prakki <Surya.Prakki@Sun.COM>
parents: 9150
diff changeset
   503
			error = EINVAL;
3b42b78e6a26 6757037 Zone-spawned LWP needs to be able to run on a processor set
Surya Prakki <Surya.Prakki@Sun.COM>
parents: 9150
diff changeset
   504
			goto err;
3b42b78e6a26 6757037 Zone-spawned LWP needs to be able to run on a processor set
Surya Prakki <Surya.Prakki@Sun.COM>
parents: 9150
diff changeset
   505
		}
3b42b78e6a26 6757037 Zone-spawned LWP needs to be able to run on a processor set
Surya Prakki <Surya.Prakki@Sun.COM>
parents: 9150
diff changeset
   506
		mutex_enter(&pp->p_lock);
3b42b78e6a26 6757037 Zone-spawned LWP needs to be able to run on a processor set
Surya Prakki <Surya.Prakki@Sun.COM>
parents: 9150
diff changeset
   507
		if ((tp = idtot(pp, id)) == NULL) {
3b42b78e6a26 6757037 Zone-spawned LWP needs to be able to run on a processor set
Surya Prakki <Surya.Prakki@Sun.COM>
parents: 9150
diff changeset
   508
			mutex_exit(&pp->p_lock);
3b42b78e6a26 6757037 Zone-spawned LWP needs to be able to run on a processor set
Surya Prakki <Surya.Prakki@Sun.COM>
parents: 9150
diff changeset
   509
			error = ESRCH;
3b42b78e6a26 6757037 Zone-spawned LWP needs to be able to run on a processor set
Surya Prakki <Surya.Prakki@Sun.COM>
parents: 9150
diff changeset
   510
			goto err;
3b42b78e6a26 6757037 Zone-spawned LWP needs to be able to run on a processor set
Surya Prakki <Surya.Prakki@Sun.COM>
parents: 9150
diff changeset
   511
		}
3b42b78e6a26 6757037 Zone-spawned LWP needs to be able to run on a processor set
Surya Prakki <Surya.Prakki@Sun.COM>
parents: 9150
diff changeset
   512
	}
3b42b78e6a26 6757037 Zone-spawned LWP needs to be able to run on a processor set
Surya Prakki <Surya.Prakki@Sun.COM>
parents: 9150
diff changeset
   513
3b42b78e6a26 6757037 Zone-spawned LWP needs to be able to run on a processor set
Surya Prakki <Surya.Prakki@Sun.COM>
parents: 9150
diff changeset
   514
	error = pset_bind_thread(tp, pset, &oldpset, projbuf, zonebuf);
3b42b78e6a26 6757037 Zone-spawned LWP needs to be able to run on a processor set
Surya Prakki <Surya.Prakki@Sun.COM>
parents: 9150
diff changeset
   515
	mutex_exit(&pp->p_lock);
3b42b78e6a26 6757037 Zone-spawned LWP needs to be able to run on a processor set
Surya Prakki <Surya.Prakki@Sun.COM>
parents: 9150
diff changeset
   516
err:
3b42b78e6a26 6757037 Zone-spawned LWP needs to be able to run on a processor set
Surya Prakki <Surya.Prakki@Sun.COM>
parents: 9150
diff changeset
   517
	mutex_exit(&pidlock);
3b42b78e6a26 6757037 Zone-spawned LWP needs to be able to run on a processor set
Surya Prakki <Surya.Prakki@Sun.COM>
parents: 9150
diff changeset
   518
3b42b78e6a26 6757037 Zone-spawned LWP needs to be able to run on a processor set
Surya Prakki <Surya.Prakki@Sun.COM>
parents: 9150
diff changeset
   519
	fss_freebuf(projbuf, FSS_ALLOC_PROJ);
3b42b78e6a26 6757037 Zone-spawned LWP needs to be able to run on a processor set
Surya Prakki <Surya.Prakki@Sun.COM>
parents: 9150
diff changeset
   520
	fss_freebuf(zonebuf, FSS_ALLOC_ZONE);
3b42b78e6a26 6757037 Zone-spawned LWP needs to be able to run on a processor set
Surya Prakki <Surya.Prakki@Sun.COM>
parents: 9150
diff changeset
   521
	mutex_exit(&cpu_lock);
3b42b78e6a26 6757037 Zone-spawned LWP needs to be able to run on a processor set
Surya Prakki <Surya.Prakki@Sun.COM>
parents: 9150
diff changeset
   522
	pool_unlock();
3b42b78e6a26 6757037 Zone-spawned LWP needs to be able to run on a processor set
Surya Prakki <Surya.Prakki@Sun.COM>
parents: 9150
diff changeset
   523
	if (opset != NULL) {
3b42b78e6a26 6757037 Zone-spawned LWP needs to be able to run on a processor set
Surya Prakki <Surya.Prakki@Sun.COM>
parents: 9150
diff changeset
   524
		if (copyout(&oldpset, opset, sizeof (psetid_t)) != 0)
3b42b78e6a26 6757037 Zone-spawned LWP needs to be able to run on a processor set
Surya Prakki <Surya.Prakki@Sun.COM>
parents: 9150
diff changeset
   525
			return (set_errno(EFAULT));
3b42b78e6a26 6757037 Zone-spawned LWP needs to be able to run on a processor set
Surya Prakki <Surya.Prakki@Sun.COM>
parents: 9150
diff changeset
   526
	}
3b42b78e6a26 6757037 Zone-spawned LWP needs to be able to run on a processor set
Surya Prakki <Surya.Prakki@Sun.COM>
parents: 9150
diff changeset
   527
	if (error != 0)
3b42b78e6a26 6757037 Zone-spawned LWP needs to be able to run on a processor set
Surya Prakki <Surya.Prakki@Sun.COM>
parents: 9150
diff changeset
   528
		return (set_errno(error));
3b42b78e6a26 6757037 Zone-spawned LWP needs to be able to run on a processor set
Surya Prakki <Surya.Prakki@Sun.COM>
parents: 9150
diff changeset
   529
	return (0);
3b42b78e6a26 6757037 Zone-spawned LWP needs to be able to run on a processor set
Surya Prakki <Surya.Prakki@Sun.COM>
parents: 9150
diff changeset
   530
}
3b42b78e6a26 6757037 Zone-spawned LWP needs to be able to run on a processor set
Surya Prakki <Surya.Prakki@Sun.COM>
parents: 9150
diff changeset
   531
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   532
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   533
pset_bind(psetid_t pset, idtype_t idtype, id_t id, psetid_t *opset)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   534
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   535
	kthread_t	*tp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   536
	proc_t		*pp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   537
	task_t		*tk;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   538
	kproject_t	*kpj;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   539
	contract_t	*ct;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   540
	zone_t		*zptr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   541
	psetid_t	oldpset;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   542
	int		error = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   543
	void		*projbuf, *zonebuf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   544
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   545
	pool_lock();
6298
060278005c21 PSARC 2008/138 Soft CPU and processor set bindings
akolb
parents: 3247
diff changeset
   546
	if ((pset != PS_QUERY) && (pset != PS_SOFT) &&
060278005c21 PSARC 2008/138 Soft CPU and processor set bindings
akolb
parents: 3247
diff changeset
   547
	    (pset != PS_HARD) && (pset != PS_QUERY_TYPE)) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   548
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   549
		 * Check if the set actually exists before checking
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   550
		 * permissions.  This is the historical error
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   551
		 * precedence.  Note that if pset was PS_MYID, the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   552
		 * cpupart_get_cpus call will change it to the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   553
		 * processor set id of the caller (or PS_NONE if the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   554
		 * caller is not bound to a processor set).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   555
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   556
		if (pool_state == POOL_ENABLED) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   557
			pool_unlock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   558
			return (set_errno(ENOTSUP));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   559
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   560
		if (cpupart_get_cpus(&pset, NULL, NULL) != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   561
			pool_unlock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   562
			return (set_errno(EINVAL));
12494
15439b11d535 PSARC/2010/181 PRIV_SYS_RES_BIND privilege
<gerald.jelinek@sun.com>
parents: 10089
diff changeset
   563
		} else if (pset != PS_NONE && secpolicy_pbind(CRED()) != 0) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   564
			pool_unlock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   565
			return (set_errno(EPERM));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   566
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   567
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   568
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   569
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   570
	 * Pre-allocate enough buffers for FSS for all active projects
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   571
	 * and for all active zones on the system.  Unused buffers will
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   572
	 * be freed later by fss_freebuf().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   573
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   574
	mutex_enter(&cpu_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   575
	projbuf = fss_allocbuf(FSS_NPROJ_BUF, FSS_ALLOC_PROJ);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   576
	zonebuf = fss_allocbuf(FSS_NPROJ_BUF, FSS_ALLOC_ZONE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   577
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   578
	switch (idtype) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   579
	case P_LWPID:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   580
		pp = curproc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   581
		mutex_enter(&pidlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   582
		mutex_enter(&pp->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   583
		if (id == P_MYID) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   584
			tp = curthread;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   585
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   586
			if ((tp = idtot(pp, id)) == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   587
				mutex_exit(&pp->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   588
				mutex_exit(&pidlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   589
				error = ESRCH;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   590
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   591
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   592
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   593
		error = pset_bind_thread(tp, pset, &oldpset, projbuf, zonebuf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   594
		mutex_exit(&pp->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   595
		mutex_exit(&pidlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   596
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   597
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   598
	case P_PID:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   599
		mutex_enter(&pidlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   600
		if (id == P_MYID) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   601
			pp = curproc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   602
		} else if ((pp = prfind(id)) == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   603
			mutex_exit(&pidlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   604
			error = ESRCH;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   605
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   606
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   607
		error = pset_bind_process(pp, pset, &oldpset, projbuf, zonebuf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   608
		mutex_exit(&pidlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   609
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   610
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   611
	case P_TASKID:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   612
		mutex_enter(&pidlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   613
		if (id == P_MYID)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   614
			id = curproc->p_task->tk_tkid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   615
		if ((tk = task_hold_by_id(id)) == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   616
			mutex_exit(&pidlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   617
			error = ESRCH;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   618
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   619
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   620
		error = pset_bind_task(tk, pset, &oldpset, projbuf, zonebuf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   621
		mutex_exit(&pidlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   622
		task_rele(tk);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   623
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   624
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   625
	case P_PROJID:
3247
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2308
diff changeset
   626
		pp = curproc;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   627
		if (id == P_MYID)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   628
			id = curprojid();
3247
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2308
diff changeset
   629
		if ((kpj = project_hold_by_id(id, pp->p_zone,
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   630
		    PROJECT_HOLD_FIND)) == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   631
			error = ESRCH;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   632
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   633
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   634
		mutex_enter(&pidlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   635
		error = pset_bind_project(kpj, pset, &oldpset, projbuf,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   636
		    zonebuf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   637
		mutex_exit(&pidlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   638
		project_rele(kpj);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   639
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   640
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   641
	case P_ZONEID:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   642
		if (id == P_MYID)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   643
			id = getzoneid();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   644
		if ((zptr = zone_find_by_id(id)) == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   645
			error = ESRCH;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   646
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   647
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   648
		mutex_enter(&pidlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   649
		error = pset_bind_zone(zptr, pset, &oldpset, projbuf, zonebuf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   650
		mutex_exit(&pidlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   651
		zone_rele(zptr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   652
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   653
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   654
	case P_CTID:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   655
		if (id == P_MYID)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   656
			id = PRCTID(curproc);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   657
		if ((ct = contract_type_ptr(process_type, id,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   658
		    curproc->p_zone->zone_uniqid)) == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   659
			error = ESRCH;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   660
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   661
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   662
		mutex_enter(&pidlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   663
		error = pset_bind_contract(ct->ct_data, pset, &oldpset, projbuf,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   664
		    zonebuf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   665
		mutex_exit(&pidlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   666
		contract_rele(ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   667
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   668
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   669
	case P_PSETID:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   670
		if (id == P_MYID || pset != PS_NONE || !INGLOBALZONE(curproc)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   671
			error = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   672
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   673
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   674
		error = pset_unbind(id, projbuf, zonebuf, idtype);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   675
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   676
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   677
	case P_ALL:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   678
		if (id == P_MYID || pset != PS_NONE || !INGLOBALZONE(curproc)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   679
			error = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   680
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   681
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   682
		error = pset_unbind(PS_NONE, projbuf, zonebuf, idtype);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   683
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   684
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   685
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   686
		error = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   687
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   688
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   689
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   690
	fss_freebuf(projbuf, FSS_ALLOC_PROJ);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   691
	fss_freebuf(zonebuf, FSS_ALLOC_ZONE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   692
	mutex_exit(&cpu_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   693
	pool_unlock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   694
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   695
	if (error != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   696
		return (set_errno(error));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   697
	if (opset != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   698
		if (copyout(&oldpset, opset, sizeof (psetid_t)) != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   699
			return (set_errno(EFAULT));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   700
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   701
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   702
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   703
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   704
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   705
 * Report load average statistics for the specified processor set.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   706
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   707
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   708
pset_getloadavg(psetid_t pset, int *buf, int nelem)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   709
{
2308
a86e1db407c3 6298715 Memory allocation in pset_getloadavg not needed
fr157268
parents: 0
diff changeset
   710
	int loadbuf[LOADAVG_NSTATS];
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   711
	int error = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   712
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   713
	if (nelem < 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   714
		return (set_errno(EINVAL));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   715
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   716
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   717
	 * We keep the same number of load average statistics for processor
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   718
	 * sets as we do for the system as a whole.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   719
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   720
	if (nelem > LOADAVG_NSTATS)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   721
		nelem = LOADAVG_NSTATS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   722
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   723
	mutex_enter(&cpu_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   724
	error = cpupart_get_loadavg(pset, loadbuf, nelem);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   725
	mutex_exit(&cpu_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   726
	if (!error && nelem && copyout(loadbuf, buf, nelem * sizeof (int)) != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   727
		error = EFAULT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   728
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   729
	if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   730
		return (set_errno(error));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   731
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   732
		return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   733
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   734
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   735
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   736
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   737
 * Return list of active processor sets, up to a maximum indicated by
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   738
 * numpsets.  The total number of processor sets is stored in the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   739
 * location pointed to by numpsets.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   740
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   741
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   742
pset_list(psetid_t *psetlist, uint_t *numpsets)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   743
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   744
	uint_t user_npsets = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   745
	uint_t real_npsets;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   746
	psetid_t *psets = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   747
	int error = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   748
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   749
	if (numpsets != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   750
		if (copyin(numpsets, &user_npsets, sizeof (uint_t)) != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   751
			return (set_errno(EFAULT));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   752
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   753
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   754
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   755
	 * Get the list of all processor sets.  First we need to find
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   756
	 * out how many there are, so we can allocate a large enough
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   757
	 * buffer.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   758
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   759
	mutex_enter(&cpu_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   760
	if (!INGLOBALZONE(curproc) && pool_pset_enabled()) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   761
		psetid_t psetid = zone_pset_get(curproc->p_zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   762
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   763
		if (psetid == PS_NONE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   764
			real_npsets = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   765
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   766
			real_npsets = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   767
			psets = kmem_alloc(real_npsets * sizeof (psetid_t),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   768
			    KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   769
			psets[0] = psetid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   770
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   771
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   772
		real_npsets = cpupart_list(0, NULL, CP_ALL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   773
		if (real_npsets) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   774
			psets = kmem_alloc(real_npsets * sizeof (psetid_t),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   775
			    KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   776
			(void) cpupart_list(psets, real_npsets, CP_ALL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   777
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   778
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   779
	mutex_exit(&cpu_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   780
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   781
	if (user_npsets > real_npsets)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   782
		user_npsets = real_npsets;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   783
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   784
	if (numpsets != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   785
		if (copyout(&real_npsets, numpsets, sizeof (uint_t)) != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   786
			error = EFAULT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   787
		else if (psetlist != NULL && user_npsets != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   788
			if (copyout(psets, psetlist,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   789
			    user_npsets * sizeof (psetid_t)) != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   790
				error = EFAULT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   791
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   792
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   793
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   794
	if (real_npsets)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   795
		kmem_free(psets, real_npsets * sizeof (psetid_t));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   796
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   797
	if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   798
		return (set_errno(error));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   799
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   800
		return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   801
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   802
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   803
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   804
pset_setattr(psetid_t pset, uint_t attr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   805
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   806
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   807
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   808
	if (secpolicy_pset(CRED()) != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   809
		return (set_errno(EPERM));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   810
	pool_lock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   811
	if (pool_state == POOL_ENABLED) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   812
		pool_unlock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   813
		return (set_errno(ENOTSUP));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   814
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   815
	if (pset == PS_QUERY || PSET_BADATTR(attr)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   816
		pool_unlock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   817
		return (set_errno(EINVAL));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   818
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   819
	if ((error = cpupart_setattr(pset, attr)) != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   820
		pool_unlock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   821
		return (set_errno(error));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   822
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   823
	pool_unlock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   824
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   825
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   826
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   827
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   828
pset_getattr(psetid_t pset, uint_t *attrp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   829
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   830
	int error = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   831
	uint_t attr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   832
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   833
	if (pset == PS_QUERY)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   834
		return (set_errno(EINVAL));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   835
	if ((error = cpupart_getattr(pset, &attr)) != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   836
		return (set_errno(error));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   837
	if (copyout(&attr, attrp, sizeof (uint_t)) != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   838
		return (set_errno(EFAULT));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   839
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   840
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   841
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   842
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   843
pset(int subcode, long arg1, long arg2, long arg3, long arg4)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   844
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   845
	switch (subcode) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   846
	case PSET_CREATE:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   847
		return (pset_create((psetid_t *)arg1));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   848
	case PSET_DESTROY:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   849
		return (pset_destroy((psetid_t)arg1));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   850
	case PSET_ASSIGN:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   851
		return (pset_assign((psetid_t)arg1,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   852
		    (processorid_t)arg2, (psetid_t *)arg3, 0));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   853
	case PSET_INFO:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   854
		return (pset_info((psetid_t)arg1, (int *)arg2,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   855
		    (uint_t *)arg3, (processorid_t *)arg4));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   856
	case PSET_BIND:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   857
		return (pset_bind((psetid_t)arg1, (idtype_t)arg2,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   858
		    (id_t)arg3, (psetid_t *)arg4));
10089
3b42b78e6a26 6757037 Zone-spawned LWP needs to be able to run on a processor set
Surya Prakki <Surya.Prakki@Sun.COM>
parents: 9150
diff changeset
   859
	case PSET_BIND_LWP:
3b42b78e6a26 6757037 Zone-spawned LWP needs to be able to run on a processor set
Surya Prakki <Surya.Prakki@Sun.COM>
parents: 9150
diff changeset
   860
		return (pset_bind_lwp((psetid_t)arg1, (id_t)arg2,
3b42b78e6a26 6757037 Zone-spawned LWP needs to be able to run on a processor set
Surya Prakki <Surya.Prakki@Sun.COM>
parents: 9150
diff changeset
   861
		    (pid_t)arg3, (psetid_t *)arg4));
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   862
	case PSET_GETLOADAVG:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   863
		return (pset_getloadavg((psetid_t)arg1, (int *)arg2,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   864
		    (int)arg3));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   865
	case PSET_LIST:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   866
		return (pset_list((psetid_t *)arg1, (uint_t *)arg2));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   867
	case PSET_SETATTR:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   868
		return (pset_setattr((psetid_t)arg1, (uint_t)arg2));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   869
	case PSET_GETATTR:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   870
		return (pset_getattr((psetid_t)arg1, (uint_t *)arg2));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   871
	case PSET_ASSIGN_FORCED:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   872
		return (pset_assign((psetid_t)arg1,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   873
		    (processorid_t)arg2, (psetid_t *)arg3, 1));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   874
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   875
		return (set_errno(EINVAL));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   876
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   877
}