On Wed 16-08-17 14:17:23, Andreas Dilger wrote: > On Aug 16, 2017, at 9:41 AM, Jan Kara <jack@xxxxxxx> wrote: > > > > dq_data_lock is currently used to protect all modifications of quota > > accounting information, consistency of quota accounting on the inode, > > and dquot pointers from inode. As a result contention on the lock can be > > pretty heavy. > > > > Reduce the contention on the lock by protecting quota accounting > > information by a new dquot->dq_dqb_lock and consistency of quota > > accounting with inode usage by inode->i_lock. > > > > This change reduces time to create 500000 files on ext4 on ramdisk by 50 > > different processes in separate directories by 6% when user quota is > > turned on. When those 50 processes belong to 50 different users, the > > improvement is about 9%. > > > > Signed-off-by: Jan Kara <jack@xxxxxxx> > > > > @@ -1604,33 +1628,41 @@ int __dquot_alloc_space(struct inode *inode, qsize_t number, int flags) > > > > dquots = i_dquot(inode); > > index = srcu_read_lock(&dquot_srcu); > > - spin_lock(&dq_data_lock); > > + spin_lock(&inode->i_lock); > > for (cnt = 0; cnt < MAXQUOTAS; cnt++) { > > if (!dquots[cnt]) > > continue; > > - ret = check_bdq(dquots[cnt], number, > > - !(flags & DQUOT_SPACE_WARN), &warn[cnt]); > > - if (ret && !(flags & DQUOT_SPACE_NOFAIL)) { > > - spin_unlock(&dq_data_lock); > > + if (flags & DQUOT_SPACE_RESERVE) { > > + ret = dquot_add_space(dquots[cnt], 0, number, flags, > > + &warn[cnt]); > > + } else { > > + ret = dquot_add_space(dquots[cnt], number, 0, flags, > > + &warn[cnt]); > > + } > > Minor nit - no need for braces around these single-line functions. Yeah, but I prefer braces in case lines are wrapped... > > diff --git a/include/linux/quota.h b/include/linux/quota.h > > index eccc1cb6274e..4b5180efff21 100644 > > --- a/include/linux/quota.h > > +++ b/include/linux/quota.h > > @@ -298,6 +298,7 @@ struct dquot { > > struct list_head dq_free; /* Free list element */ > > struct list_head dq_dirty; /* List of dirty dquots */ > > struct mutex dq_lock; /* dquot IO lock */ > > + spinlock_t dq_dqb_lock; /* Lock protecting dq_dqb changes */ > > Might be good to have a comment at mem_dqblk that dq_lock is used for locking? OK, will do. Honza -- Jan Kara <jack@xxxxxxxx> SUSE Labs, CR