summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/os
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/uts/common/os')
-rw-r--r--usr/src/uts/common/os/brand.c9
-rw-r--r--usr/src/uts/common/os/exec.c13
-rw-r--r--usr/src/uts/common/os/lwp.c45
3 files changed, 35 insertions, 32 deletions
diff --git a/usr/src/uts/common/os/brand.c b/usr/src/uts/common/os/brand.c
index 61aa562f73..00f2ce0440 100644
--- a/usr/src/uts/common/os/brand.c
+++ b/usr/src/uts/common/os/brand.c
@@ -1037,7 +1037,7 @@ brand_solaris_exec(struct brand *pbrand)
/* Upon exec, reset our lwp brand data. */
(void) brand_solaris_freelwp(ttolwp(curthread), pbrand);
- (void) brand_solaris_brandlwp(ttolwp(curthread), pbrand);
+ (void) brand_solaris_initlwp(ttolwp(curthread), pbrand);
/*
* Upon exec, reset all the proc brand data, except for the elf
@@ -1081,7 +1081,7 @@ brand_solaris_forklwp(klwp_t *p, klwp_t *c, struct brand *pbrand)
/*
* Both LWPs have already had been initialized via
- * brand_solaris_brandlwp().
+ * brand_solaris_initlwp().
*/
ASSERT(p->lwp_brand != NULL);
ASSERT(c->lwp_brand != NULL);
@@ -1098,14 +1098,13 @@ brand_solaris_freelwp(klwp_t *l, struct brand *pbrand)
}
/*ARGSUSED*/
-int
-brand_solaris_brandlwp(klwp_t *l, struct brand *pbrand)
+void
+brand_solaris_initlwp(klwp_t *l, struct brand *pbrand)
{
ASSERT(l->lwp_procp->p_brand == pbrand);
ASSERT(l->lwp_procp->p_brand_data != NULL);
ASSERT(l->lwp_brand == NULL);
l->lwp_brand = (void *)-1;
- return (0);
}
/*ARGSUSED*/
diff --git a/usr/src/uts/common/os/exec.c b/usr/src/uts/common/os/exec.c
index 4b6c79997e..7e32fb0506 100644
--- a/usr/src/uts/common/os/exec.c
+++ b/usr/src/uts/common/os/exec.c
@@ -301,19 +301,20 @@ exec_common(const char *fname, const char **argp, const char **envp,
/* If necessary, brand this process/lwp before we start the exec. */
if (brandme) {
+ void *brand_data = NULL;
+
brand_setbrand(p);
- if (BROP(p)->b_brandlwp(lwp) != 0) {
+ if (BROP(p)->b_lwpdata_alloc != NULL &&
+ (brand_data = BROP(p)->b_lwpdata_alloc(p)) == NULL) {
VN_RELE(vp);
if (dir != NULL)
VN_RELE(dir);
pn_free(&resolvepn);
goto fail;
}
- if (BROP(p)->b_initlwp != NULL) {
- mutex_enter(&p->p_lock);
- BROP(p)->b_initlwp(lwp);
- mutex_exit(&p->p_lock);
- }
+ mutex_enter(&p->p_lock);
+ BROP(p)->b_initlwp(lwp, brand_data);
+ mutex_exit(&p->p_lock);
}
if ((error = gexec(&vp, &ua, &args, NULL, 0, &execsz,
diff --git a/usr/src/uts/common/os/lwp.c b/usr/src/uts/common/os/lwp.c
index 6b91e410d7..f5be1b40b3 100644
--- a/usr/src/uts/common/os/lwp.c
+++ b/usr/src/uts/common/os/lwp.c
@@ -115,7 +115,7 @@ lwp_create(void (*proc)(), caddr_t arg, size_t len, proc_t *p,
ret_tidhash_t *ret_tidhash = NULL;
int i;
int rctlfail = 0;
- boolean_t branded = B_FALSE;
+ void *brand_data = NULL;
struct ctxop *ctx = NULL;
ASSERT(cid != sysdccid); /* system threads must start in SYS */
@@ -283,6 +283,19 @@ lwp_create(void (*proc)(), caddr_t arg, size_t len, proc_t *p,
*/
lep = kmem_zalloc(sizeof (*lep), KM_SLEEP);
+ /*
+ * If necessary, speculatively allocate lwp brand data. This is done
+ * ahead of time so p_lock need not be dropped during lwp branding.
+ */
+ if (PROC_IS_BRANDED(p) && BROP(p)->b_lwpdata_alloc != NULL) {
+ if ((brand_data = BROP(p)->b_lwpdata_alloc(p)) == NULL) {
+ mutex_enter(&p->p_lock);
+ err = 1;
+ atomic_inc_32(&p->p_zone->zone_ffmisc);
+ goto error;
+ }
+ }
+
mutex_enter(&p->p_lock);
grow:
/*
@@ -682,25 +695,15 @@ grow:
t->t_pre_sys = 1;
t->t_post_sys = 1;
- mutex_exit(&p->p_lock);
- /*
- * If this is a branded process, allocate any brand-specific lwp data.
- */
- if (PROC_IS_BRANDED(p)) {
- if (BROP(p)->b_brandlwp(lwp) != 0) {
- mutex_enter(&p->p_lock);
- err = 1;
- atomic_inc_32(&p->p_zone->zone_ffmisc);
- goto error;
- }
- branded = B_TRUE;
- }
-
- mutex_enter(&p->p_lock);
-
/* Complete branded lwp initialization */
- if (branded && BROP(p)->b_initlwp != NULL) {
- BROP(p)->b_initlwp(lwp);
+ if (PROC_IS_BRANDED(p)) {
+ BROP(p)->b_initlwp(lwp, brand_data);
+ /*
+ * The b_initlwp hook is expected to consume any preallocated
+ * brand_data in a way that prepares it for deallocation by the
+ * b_freelwp hook.
+ */
+ brand_data = NULL;
}
/*
@@ -762,8 +765,8 @@ error:
if (cid != NOCLASS && bufp != NULL)
CL_FREE(cid, bufp);
- if (branded) {
- BROP(p)->b_freelwp(lwp);
+ if (brand_data != NULL) {
+ BROP(p)->b_lwpdata_free(brand_data);
}
mutex_exit(&p->p_lock);