fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * CDDL HEADER START
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The contents of this file are subject to the terms of the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Common Development and Distribution License (the "License").
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * You may not use this file except in compliance with the License.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * or http://www.opensolaris.org/os/licensing.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * See the License for the specific language governing permissions
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and limitations under the License.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * When distributing Covered Code, include this CDDL HEADER in each
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If applicable, add the following below this CDDL HEADER, with the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner]
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * CDDL HEADER END
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Use is subject to license terms.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/types.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/ksynch.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/errno.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/cmn_err.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/conf.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/kmem.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/ddi.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define __NSC_GEN__
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/nsctl/nsc_rmspin.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include "../nsctl.h"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include "nskernd.h"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestruct nsc_nlwp {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct nsc_nlwp *next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte void (*fn)(void *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte void *arg;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte volatile int ready;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int errno;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kcondvar_t child_cv;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortekmutex_t nsc_proc_lock;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortekcondvar_t nsc_proc_cv;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic struct nsc_nlwp *nsc_nlwp_top;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_nsc_start_proc(void)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_init(&nsc_proc_lock, NULL, MUTEX_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_init(&nsc_proc_cv, NULL, CV_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_nsc_stop_proc(void)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_destroy(&nsc_proc_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_destroy(&nsc_proc_cv);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Create a daemon (server) proc.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If 'rt' is TRUE, then increase the scheduling priority of the lwp.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Exactly how, if at all, this feature is implemented is at the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * discretion of nskernd.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns 0 or errno.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortensc_create_process(void (*func)(void *), void *arg, boolean_t rt)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct nsc_nlwp *nlwp, **nlwpp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct nskernd *nsk = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rc = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nlwp = kmem_zalloc(sizeof (*nlwp), KM_NOSLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsk = kmem_zalloc(sizeof (*nsk), KM_NOSLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!nlwp || !nsk) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (nlwp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(nlwp, sizeof (*nlwp));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (nsk) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(nsk, sizeof (*nsk));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ENOMEM);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nlwp->fn = func;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nlwp->arg = arg;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&nsc_proc_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nlwp->next = nsc_nlwp_top;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_nlwp_top = nlwp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&nsc_proc_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsk->command = NSKERND_NEWLWP;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsk->data1 = (uint64_t)(unsigned long)nlwp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsk->data2 = (uint64_t)rt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = nskernd_get(nsk);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* user level returns error in nsk->data1 */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!rc && nsk->data1)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = nsk->data1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&nsc_proc_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!rc) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * wait for the child to start and check in.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (! nlwp->ready) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_wait(&nsc_proc_cv, &nsc_proc_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * remove from list of outstanding requests.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (nlwpp = &nsc_nlwp_top; (*nlwpp); nlwpp = &((*nlwpp)->next)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (*nlwpp == nlwp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *nlwpp = nlwp->next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&nsc_proc_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(nlwp, sizeof (*nlwp));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(nsk, sizeof (*nsk));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Child lwp calls this function when it returns to the kernel.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Check if the args are still on the pending list. If they are, then
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * run the required function. If they are not, then something went
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * wrong, so just return back to userland and die.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortensc_runlwp(uint64_t arg)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct nsc_nlwp *nlwp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte void (*fn)(void *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte void *fn_arg;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fn_arg = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fn = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&nsc_proc_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * check that the request is still on the list of work to do
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (nlwp = nsc_nlwp_top; nlwp; nlwp = nlwp->next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (nlwp == (struct nsc_nlwp *)(unsigned long)arg) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fn_arg = nlwp->arg;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fn = nlwp->fn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* mark as ready */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nlwp->ready = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_broadcast(&nsc_proc_cv);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&nsc_proc_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fn) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (*fn)(fn_arg);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Create a thread that acquires an inter-node lock.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * mode - 0 (read), 1 (write).
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * lockp - used to return the opaque address of a sync structure, which
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * must be passed to nsc_do_unlock() later.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns 0 or errno.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortensc_do_lock(int mode, void **lockp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct nsc_nlwp *nlwp = NULL, **nlwpp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct nskernd *nsk = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rc = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nlwp = kmem_zalloc(sizeof (*nlwp), KM_NOSLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsk = kmem_zalloc(sizeof (*nsk), KM_NOSLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!nlwp || !nsk) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (nlwp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(nlwp, sizeof (*nlwp));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (nsk) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(nsk, sizeof (*nsk));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ENOMEM);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_init(&nlwp->child_cv, NULL, CV_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&nsc_proc_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nlwp->next = nsc_nlwp_top;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_nlwp_top = nlwp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&nsc_proc_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsk->command = NSKERND_LOCK;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsk->data1 = (uint64_t)(unsigned long)nlwp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsk->data2 = (uint64_t)mode;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = nskernd_get(nsk);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* user level returns error in nsk->data1 */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!rc && nsk->data1)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = nsk->data1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&nsc_proc_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!rc) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * wait for the child to start and check in.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (! nlwp->ready) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_wait(&nsc_proc_cv, &nsc_proc_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* retrieve errno from child's lock operation */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = (int)nlwp->errno;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * error - remove from list of outstanding requests as
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * child will not be checking in (nskernd_get() failed
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * or user thread create failed) or will not be waiting
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * (child thread lock failure).
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (nlwpp = &nsc_nlwp_top; (*nlwpp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nlwpp = &((*nlwpp)->next)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (*nlwpp == nlwp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *nlwpp = nlwp->next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&nsc_proc_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_destroy(&nlwp->child_cv);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(nlwp, sizeof (*nlwp));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(nsk, sizeof (*nsk));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *lockp = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* success, return argument for nsc_do_unlock() */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&nsc_proc_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(nsk, sizeof (*nsk));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *lockp = nlwp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortensc_do_unlock(void *arg)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct nsc_nlwp *nlwp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* find child on work list */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&nsc_proc_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (nlwp = nsc_nlwp_top; nlwp; nlwp = nlwp->next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (nlwp == (struct nsc_nlwp *)arg) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* signal unlock */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nlwp->ready = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_broadcast(&nlwp->child_cv);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&nsc_proc_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Lock child thread calls this function when it returns to the kernel.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Check if the args are still on the pending list. If they are, then
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * post the lock results and wait for the unlock. If they are not,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * then something went wrong, so just return back to userland and die.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortensc_lockchild(uint64_t arg, uint64_t errno)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct nsc_nlwp *nlwp, **nlwpp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!arg) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&nsc_proc_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * check that the request is still on the list of work to do
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (nlwp = nsc_nlwp_top; nlwp; nlwp = nlwp->next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (nlwp == (struct nsc_nlwp *)(unsigned long)arg) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* mark as ready */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nlwp->errno = (int)errno;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nlwp->ready = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_broadcast(&nsc_proc_cv);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!nlwp || errno) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Error - either this request is no longer on the work
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * queue, or there was an error in the userland lock code
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * in which case the lock caller (currently blocked in
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nsc_do_lock() will do the cleanup.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&nsc_proc_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * no errors, so wait for an unlock
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (nlwp->ready) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_wait(&nlwp->child_cv, &nsc_proc_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * remove self from list of outstanding requests.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (nlwpp = &nsc_nlwp_top; (*nlwpp); nlwpp = &((*nlwpp)->next)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (*nlwpp == nlwp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *nlwpp = nlwp->next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * cleanup
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_destroy(&nlwp->child_cv);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(nlwp, sizeof (*nlwp));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&nsc_proc_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}