lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <YmLfLX5Ce8+VF2G4@slm.duckdns.org>
Date:   Fri, 22 Apr 2022 07:00:29 -1000
From:   Tejun Heo <tj@...nel.org>
To:     Imran Khan <imran.f.khan@...cle.com>
Cc:     viro@...iv.linux.org.uk, gregkh@...uxfoundation.org,
        ebiederm@...ssion.com, linux-kernel@...r.kernel.org
Subject: Re: [PATCH v8 05/10] kernfs: Replace global kernfs_open_file_mutex
 with hashed mutexes.

On Sun, Apr 10, 2022 at 12:37:14PM +1000, Imran Khan wrote:
> diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c
> index 214b48d59148..0946ab341ce4 100644
> --- a/fs/kernfs/file.c
> +++ b/fs/kernfs/file.c
> @@ -19,18 +19,14 @@
>  #include "kernfs-internal.h"
>  
>  /*
> - * There's one kernfs_open_file for each open file and one kernfs_open_node
> - * for each kernfs_node with one or more open files.
> - *
> + * kernfs locks
> + */
> +extern struct kernfs_global_locks *kernfs_locks;

This should be in a header file, right?

> @@ -545,7 +543,7 @@ static int kernfs_get_open_node(struct kernfs_node *kn,
>  	 * need rcu_read_lock to ensure its existence.
>  	 */
>  	on = rcu_dereference_protected(kn->attr.open,
> -				   lockdep_is_held(&kernfs_open_file_mutex));
> +				   lockdep_is_held(mutex));
>  	if (on) {
>  		list_add_tail(&of->list, &on->files);
>  		mutex_unlock(mutex);
> @@ -593,10 +591,10 @@ static void kernfs_put_open_node(struct kernfs_node *kn,
>  	mutex = kernfs_open_file_mutex_lock(kn);
>  
>  	on = rcu_dereference_protected(kn->attr.open,
> -				       lockdep_is_held(&kernfs_open_file_mutex));
> +				       lockdep_is_held(mutex));
>  
>  	if (!on) {
> -		mutex_unlock(&kernfs_open_file_mutex);
> +		mutex_unlock(mutex);
>  		return;
>  	}

Don't above chunks belong to the previous patch?

> @@ -769,6 +767,10 @@ static int kernfs_fop_release(struct inode *inode, struct file *filp)
>  	struct mutex *mutex = NULL;
>  
>  	if (kn->flags & KERNFS_HAS_RELEASE) {
> +		/**
> +		 * Callers of kernfs_fop_release, don't need global
> +		 * exclusion so using hashed mutex here is safe.
> +		 */

I don't think we use /** for in-line comments. Just do balanced wings.

 /*
  * ....
  */

besides, I'm not sure the comment is helping that much. It'd be better to
have a comment describing the locking rules comprehensively around the lock
definition and/or helpers.

>  		mutex = kernfs_open_file_mutex_lock(kn);
>  		kernfs_release_file(kn, of);
>  		mutex_unlock(mutex);
> @@ -796,9 +798,9 @@ void kernfs_drain_open_files(struct kernfs_node *kn)
>  
>  	mutex = kernfs_open_file_mutex_lock(kn);
>  	on = rcu_dereference_check(kn->attr.open,
> -				   lockdep_is_held(&kernfs_open_file_mutex));
> +				   lockdep_is_held(mutex));
>  	if (!on) {
> -		mutex_unlock(&kernfs_open_file_mutex);
> +		mutex_unlock(mutex);

Again, should be in the previous patch.

> +void __init kernfs_lock_init(void)
> +{
> +	int count;
> +
> +	kernfs_locks = kmalloc(sizeof(struct kernfs_global_locks), GFP_KERNEL);
> +	WARN_ON(!kernfs_locks);
> +
> +	for (count = 0; count < NR_KERNFS_LOCKS; count++)
> +		mutex_init(&kernfs_locks->open_file_mutex[count].lock);
> +}

Does this need to be a separate function?

>  void __init kernfs_init(void)
>  {
>  	kernfs_node_cache = kmem_cache_create("kernfs_node_cache",
> @@ -397,4 +409,6 @@ void __init kernfs_init(void)
>  	kernfs_iattrs_cache  = kmem_cache_create("kernfs_iattrs_cache",
>  					      sizeof(struct kernfs_iattrs),
>  					      0, SLAB_PANIC, NULL);
> +
> +	kernfs_lock_init();
>  }
> diff --git a/include/linux/kernfs.h b/include/linux/kernfs.h
> index 2dd9c8df0f4f..cc514bda0ae7 100644
> --- a/include/linux/kernfs.h
> +++ b/include/linux/kernfs.h
...
> + * filp->private_data points to seq_file whose ->private points to
> + * kernfs_open_file.
> + * kernfs_open_files are chained at kernfs_open_node->files, which is
> + * protected by kernfs_open_file_mutex.lock.

Can you either flow the sentences together or have a blank line inbetween if
they're supposed to be in separate paragraphs?

> + */
> +struct kernfs_open_file_mutex {
> +	struct mutex lock;
> +} ____cacheline_aligned_in_smp;

Is there a reason to define the outer struct?

> +/*
> + * To reduce possible contention in sysfs access, arising due to single
> + * locks, use an array of locks and use kernfs_node object address as
> + * hash keys to get the index of these locks.
> + */
> +struct kernfs_global_locks {
> +	struct kernfs_open_file_mutex open_file_mutex[NR_KERNFS_LOCKS];
> +};

Ditto, why not just define the array directly?

> +void kernfs_lock_init(void);

Does this function need to be exposed?

Thanks.

-- 
tejun

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ