Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4a6a4499 authored by Jonathan Corbet's avatar Jonathan Corbet
Browse files

Fix a lockdep warning in fasync_helper()



Lockdep gripes if file->f_lock is taken in a no-IRQ situation, since that
is not always the case.  We don't really want to disable IRQs for every
acquisition of f_lock; instead, just move it outside of fasync_lock.

Reported-by: default avatarBartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Reported-by: default avatarLarry Finger <Larry.Finger@lwfinger.net>
Reported-by: default avatarWu Fengguang <fengguang.wu@intel.com>
Signed-off-by: default avatarJonathan Corbet <corbet@lwn.net>
parent 996ff68d
Loading
Loading
Loading
Loading
+7 −3
Original line number Diff line number Diff line
@@ -531,6 +531,12 @@ int fasync_helper(int fd, struct file * filp, int on, struct fasync_struct **fap
		if (!new)
			return -ENOMEM;
	}

	/*
	 * We need to take f_lock first since it's not an IRQ-safe
	 * lock.
	 */
	spin_lock(&filp->f_lock);
	write_lock_irq(&fasync_lock);
	for (fp = fapp; (fa = *fp) != NULL; fp = &fa->fa_next) {
		if (fa->fa_file == filp) {
@@ -555,14 +561,12 @@ int fasync_helper(int fd, struct file * filp, int on, struct fasync_struct **fap
		result = 1;
	}
out:
	/* Fix up FASYNC bit while still holding fasync_lock */
	spin_lock(&filp->f_lock);
	if (on)
		filp->f_flags |= FASYNC;
	else
		filp->f_flags &= ~FASYNC;
	spin_unlock(&filp->f_lock);
	write_unlock_irq(&fasync_lock);
	spin_unlock(&filp->f_lock);
	return result;
}

+1 −1
Original line number Diff line number Diff line
@@ -848,7 +848,7 @@ struct file {
#define f_dentry	f_path.dentry
#define f_vfsmnt	f_path.mnt
	const struct file_operations	*f_op;
	spinlock_t		f_lock;  /* f_ep_links, f_flags */
	spinlock_t		f_lock;  /* f_ep_links, f_flags, no IRQ */
	atomic_long_t		f_count;
	unsigned int 		f_flags;
	fmode_t			f_mode;