Index | Thread | Search

From:
Alexander Bluhm <bluhm@openbsd.org>
Subject:
Re: Take `sysctl_lock' before kernel lock
To:
Vitaliy Makkoveev <mvs@openbsd.org>
Cc:
tech@openbsd.org
Date:
Mon, 5 Aug 2024 13:06:04 +0200

Download raw body.

Thread
On Fri, Aug 02, 2024 at 11:46:58PM +0300, Vitaliy Makkoveev wrote:
> It's better to wait system-wide kernel lock acquisition after local
> `sysctl_lock'.

OK bluhm@

In general the order
	KERNEL_LOCK();
	rw_enter();
does not make sense.  rw_enter() may kernel unlock and lock again.
So it is better to start rw_enter() without holding kenrel lock.

> Index: sys/kern/kern_sysctl.c
> ===================================================================
> RCS file: /cvs/src/sys/kern/kern_sysctl.c,v
> diff -u -p -r1.430 kern_sysctl.c
> --- sys/kern/kern_sysctl.c	2 Aug 2024 14:34:45 -0000	1.430
> +++ sys/kern/kern_sysctl.c	2 Aug 2024 15:31:34 -0000
> @@ -172,26 +172,25 @@ sysctl_vslock(void *addr, size_t len)
>  {
>  	int error;
>  
> -	KERNEL_LOCK();
>  	error = rw_enter(&sysctl_lock, RW_WRITE|RW_INTR);
>  	if (error)
> -		goto out;
> +		return error;
> +	KERNEL_LOCK();
>  
>  	if (addr) {
>  		if (atop(len) > uvmexp.wiredmax - uvmexp.wired) {
>  			error = ENOMEM;
> -			goto out2;
> +			goto out;
>  		}
>  		error = uvm_vslock(curproc, addr, len, PROT_READ | PROT_WRITE);
>  		if (error)
> -			goto out2;
> +			goto out;
>  	}
>  
>  	return (0);
> -out2:
> -	rw_exit_write(&sysctl_lock);
>  out:
>  	KERNEL_UNLOCK();
> +	rw_exit_write(&sysctl_lock);
>  	return (error);
>  }
>  
> @@ -202,8 +201,8 @@ sysctl_vsunlock(void *addr, size_t len)
>  
>  	if (addr)
>  		uvm_vsunlock(curproc, addr, len);
> -	rw_exit_write(&sysctl_lock);
>  	KERNEL_UNLOCK();
> +	rw_exit_write(&sysctl_lock);
>  }
>  
>  int