Home | History | Annotate | Line # | Download | only in rumpkern
      1  1.11  riastrad /*	$NetBSD: klock.c,v 1.11 2023/06/23 21:09:44 riastradh Exp $	*/
      2   1.1     pooka 
      3   1.1     pooka /*
      4   1.1     pooka  * Copyright (c) 2007-2010 Antti Kantee.  All Rights Reserved.
      5   1.1     pooka  *
      6   1.1     pooka  * Development of this software was supported by the
      7   1.1     pooka  * Finnish Cultural Foundation.
      8   1.1     pooka  *
      9   1.1     pooka  * Redistribution and use in source and binary forms, with or without
     10   1.1     pooka  * modification, are permitted provided that the following conditions
     11   1.1     pooka  * are met:
     12   1.1     pooka  * 1. Redistributions of source code must retain the above copyright
     13   1.1     pooka  *    notice, this list of conditions and the following disclaimer.
     14   1.1     pooka  * 2. Redistributions in binary form must reproduce the above copyright
     15   1.1     pooka  *    notice, this list of conditions and the following disclaimer in the
     16   1.1     pooka  *    documentation and/or other materials provided with the distribution.
     17   1.1     pooka  *
     18   1.1     pooka  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
     19   1.1     pooka  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     20   1.1     pooka  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     21   1.1     pooka  * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     22   1.1     pooka  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     23   1.1     pooka  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     24   1.1     pooka  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     25   1.1     pooka  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     26   1.1     pooka  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     27   1.1     pooka  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     28   1.1     pooka  * SUCH DAMAGE.
     29   1.1     pooka  */
     30   1.1     pooka 
     31   1.1     pooka #include <sys/cdefs.h>
     32  1.11  riastrad __KERNEL_RCSID(0, "$NetBSD: klock.c,v 1.11 2023/06/23 21:09:44 riastradh Exp $");
     33   1.1     pooka 
     34   1.1     pooka #include <sys/param.h>
     35   1.1     pooka #include <sys/systm.h>
     36   1.5     pooka #include <sys/evcnt.h>
     37   1.1     pooka 
     38   1.9     pooka #include <rump-sys/kern.h>
     39   1.9     pooka 
     40   1.1     pooka #include <rump/rumpuser.h>
     41   1.1     pooka 
     42   1.1     pooka /*
     43   1.1     pooka  * giant lock
     44   1.1     pooka  */
     45   1.1     pooka 
     46   1.3     pooka struct rumpuser_mtx *rump_giantlock;
     47   1.3     pooka static int giantcnt;
     48   1.3     pooka static struct lwp *giantowner;
     49   1.1     pooka 
     50   1.5     pooka static struct evcnt ev_biglock_fast;
     51   1.5     pooka static struct evcnt ev_biglock_slow;
     52   1.5     pooka static struct evcnt ev_biglock_recurse;
     53   1.5     pooka 
     54   1.5     pooka void
     55   1.5     pooka rump_biglock_init(void)
     56   1.5     pooka {
     57   1.5     pooka 
     58   1.5     pooka 	evcnt_attach_dynamic(&ev_biglock_fast, EVCNT_TYPE_MISC, NULL,
     59   1.5     pooka 	    "rump biglock", "fast");
     60   1.5     pooka 	evcnt_attach_dynamic(&ev_biglock_slow, EVCNT_TYPE_MISC, NULL,
     61   1.5     pooka 	    "rump biglock", "slow");
     62   1.5     pooka 	evcnt_attach_dynamic(&ev_biglock_recurse, EVCNT_TYPE_MISC, NULL,
     63   1.5     pooka 	    "rump biglock", "recurse");
     64   1.5     pooka }
     65   1.5     pooka 
     66   1.1     pooka void
     67   1.3     pooka rump_kernel_bigwrap(int *nlocks)
     68   1.1     pooka {
     69   1.1     pooka 
     70  1.11  riastrad 	KASSERTMSG(giantcnt > 0, "giantcnt=%d", giantcnt);
     71  1.11  riastrad 	KASSERTMSG(curlwp == giantowner, "curlwp=%p giantowner=%p",
     72  1.11  riastrad 	    curlwp, giantowner);
     73  1.10   msaitoh 	giantowner = NULL;
     74   1.3     pooka 	*nlocks = giantcnt;
     75   1.3     pooka 	giantcnt = 0;
     76   1.1     pooka }
     77   1.1     pooka 
     78   1.1     pooka void
     79   1.3     pooka rump_kernel_bigunwrap(int nlocks)
     80   1.1     pooka {
     81   1.1     pooka 
     82   1.3     pooka 	KASSERT(giantowner == NULL);
     83   1.3     pooka 	giantowner = curlwp;
     84   1.3     pooka 	giantcnt = nlocks;
     85   1.1     pooka }
     86   1.1     pooka 
     87   1.1     pooka void
     88   1.1     pooka _kernel_lock(int nlocks)
     89   1.1     pooka {
     90   1.3     pooka 	struct lwp *l = curlwp;
     91   1.1     pooka 
     92   1.3     pooka 	while (nlocks) {
     93   1.3     pooka 		if (giantowner == l) {
     94   1.3     pooka 			giantcnt += nlocks;
     95   1.3     pooka 			nlocks = 0;
     96   1.5     pooka 			ev_biglock_recurse.ev_count++;
     97   1.3     pooka 		} else {
     98   1.8     pooka 			if (rumpuser_mutex_tryenter(rump_giantlock) != 0) {
     99   1.3     pooka 				rump_unschedule_cpu1(l, NULL);
    100   1.3     pooka 				rumpuser_mutex_enter_nowrap(rump_giantlock);
    101   1.3     pooka 				rump_schedule_cpu(l);
    102   1.5     pooka 				ev_biglock_slow.ev_count++;
    103   1.5     pooka 			} else {
    104   1.5     pooka 				ev_biglock_fast.ev_count++;
    105   1.3     pooka 			}
    106   1.3     pooka 			giantowner = l;
    107   1.3     pooka 			giantcnt = 1;
    108   1.3     pooka 			nlocks--;
    109   1.1     pooka 		}
    110   1.1     pooka 	}
    111   1.1     pooka }
    112   1.1     pooka 
    113   1.1     pooka void
    114   1.1     pooka _kernel_unlock(int nlocks, int *countp)
    115   1.1     pooka {
    116   1.1     pooka 
    117   1.3     pooka 	if (giantowner != curlwp) {
    118   1.1     pooka 		KASSERT(nlocks == 0);
    119   1.1     pooka 		if (countp)
    120   1.1     pooka 			*countp = 0;
    121   1.1     pooka 		return;
    122   1.1     pooka 	}
    123   1.1     pooka 
    124   1.1     pooka 	if (countp)
    125   1.3     pooka 		*countp = giantcnt;
    126   1.1     pooka 	if (nlocks == 0)
    127   1.3     pooka 		nlocks = giantcnt;
    128   1.1     pooka 	if (nlocks == -1) {
    129   1.3     pooka 		KASSERT(giantcnt == 1);
    130   1.1     pooka 		nlocks = 1;
    131   1.1     pooka 	}
    132   1.3     pooka 	KASSERT(nlocks <= giantcnt);
    133   1.1     pooka 	while (nlocks--) {
    134   1.3     pooka 		giantcnt--;
    135   1.3     pooka 	}
    136   1.3     pooka 
    137   1.3     pooka 	if (giantcnt == 0) {
    138   1.3     pooka 		giantowner = NULL;
    139   1.1     pooka 		rumpuser_mutex_exit(rump_giantlock);
    140   1.1     pooka 	}
    141   1.1     pooka }
    142   1.1     pooka 
    143   1.4       mrg bool
    144   1.4       mrg _kernel_locked_p(void)
    145   1.4       mrg {
    146   1.4       mrg 
    147   1.4       mrg 	return giantowner == curlwp;
    148   1.4       mrg }
    149   1.4       mrg 
    150   1.1     pooka void
    151   1.1     pooka rump_user_unschedule(int nlocks, int *countp, void *interlock)
    152   1.1     pooka {
    153   1.1     pooka 
    154   1.1     pooka 	_kernel_unlock(nlocks, countp);
    155   1.1     pooka 	/*
    156   1.1     pooka 	 * XXX: technically we should unschedule_cpu1() here, but that
    157   1.1     pooka 	 * requires rump_intr_enter/exit to be implemented.
    158   1.1     pooka 	 */
    159   1.1     pooka 	rump_unschedule_cpu_interlock(curlwp, interlock);
    160   1.1     pooka }
    161   1.1     pooka 
    162   1.1     pooka void
    163   1.1     pooka rump_user_schedule(int nlocks, void *interlock)
    164   1.1     pooka {
    165   1.1     pooka 
    166   1.1     pooka 	rump_schedule_cpu_interlock(curlwp, interlock);
    167   1.1     pooka 
    168   1.1     pooka 	if (nlocks)
    169   1.1     pooka 		_kernel_lock(nlocks);
    170   1.1     pooka }
    171