diff mbox

quota: optimize i_dquot access

Message ID 20150212093637.6005.69788.stgit@buzz (mailing list archive)
State New, archived
Headers show

Commit Message

Konstantin Khlebnikov Feb. 12, 2015, 9:36 a.m. UTC
Remove redundant calls of i_dquot(), keep pointer in local variable.

add/remove: 0/0 grow/shrink: 3/7 up/down: 40/-278 (-238)
function                                     old     new   delta
__dquot_free_space                           734     750     +16
__dquot_alloc_space                          484     500     +16
dquot_free_inode                             324     332      +8
dquot_drop                                    82      69     -13
vfs_load_quota_inode                        1357    1341     -16
dquot_reclaim_space_nodirty                  348     316     -32
dquot_disable                               1980    1944     -36
dquot_claim_space_nodirty                    354     314     -40
__dquot_drop                                 125      83     -42
__dquot_initialize                           522     423     -99

Signed-off-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
---
 fs/quota/dquot.c |   63 +++++++++++++++++++++++++++++++++---------------------
 1 file changed, 39 insertions(+), 24 deletions(-)


--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Comments

Jan Kara Feb. 12, 2015, 2:03 p.m. UTC | #1
On Thu 12-02-15 12:36:37, Konstantin Khlebnikov wrote:
> Remove redundant calls of i_dquot(), keep pointer in local variable.
> 
> add/remove: 0/0 grow/shrink: 3/7 up/down: 40/-278 (-238)
> function                                     old     new   delta
> __dquot_free_space                           734     750     +16
> __dquot_alloc_space                          484     500     +16
> dquot_free_inode                             324     332      +8
> dquot_drop                                    82      69     -13
> vfs_load_quota_inode                        1357    1341     -16
> dquot_reclaim_space_nodirty                  348     316     -32
> dquot_disable                               1980    1944     -36
> dquot_claim_space_nodirty                    354     314     -40
> __dquot_drop                                 125      83     -42
> __dquot_initialize                           522     423     -99
  Thanks. I've added the patch to my tree.

								Honza

> 
> Signed-off-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
> ---
>  fs/quota/dquot.c |   63 +++++++++++++++++++++++++++++++++---------------------
>  1 file changed, 39 insertions(+), 24 deletions(-)
> 
> diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
> index 0ccd4ba..2112ed3 100644
> --- a/fs/quota/dquot.c
> +++ b/fs/quota/dquot.c
> @@ -900,14 +900,17 @@ static inline struct dquot **i_dquot(struct inode *inode)
>  
>  static int dqinit_needed(struct inode *inode, int type)
>  {
> +	struct dquot * const *dquots;
>  	int cnt;
>  
>  	if (IS_NOQUOTA(inode))
>  		return 0;
> +
> +	dquots = i_dquot(inode);
>  	if (type != -1)
> -		return !i_dquot(inode)[type];
> +		return !dquots[type];
>  	for (cnt = 0; cnt < MAXQUOTAS; cnt++)
> -		if (!i_dquot(inode)[cnt])
> +		if (!dquots[cnt])
>  			return 1;
>  	return 0;
>  }
> @@ -970,12 +973,13 @@ static void add_dquot_ref(struct super_block *sb, int type)
>  static void remove_inode_dquot_ref(struct inode *inode, int type,
>  				   struct list_head *tofree_head)
>  {
> -	struct dquot *dquot = i_dquot(inode)[type];
> +	struct dquot **dquots = i_dquot(inode);
> +	struct dquot *dquot = dquots[type];
>  
> -	i_dquot(inode)[type] = NULL;
>  	if (!dquot)
>  		return;
>  
> +	dquots[type] = NULL;
>  	if (list_empty(&dquot->dq_free)) {
>  		/*
>  		 * The inode still has reference to dquot so it can't be in the
> @@ -1389,13 +1393,15 @@ static int dquot_active(const struct inode *inode)
>  static void __dquot_initialize(struct inode *inode, int type)
>  {
>  	int cnt, init_needed = 0;
> -	struct dquot *got[MAXQUOTAS];
> +	struct dquot **dquots, *got[MAXQUOTAS];
>  	struct super_block *sb = inode->i_sb;
>  	qsize_t rsv;
>  
>  	if (!dquot_active(inode))
>  		return;
>  
> +	dquots = i_dquot(inode);
> +
>  	/* First get references to structures we might need. */
>  	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
>  		struct kqid qid;
> @@ -1407,7 +1413,7 @@ static void __dquot_initialize(struct inode *inode, int type)
>  		 * we check it without locking here to avoid unnecessary
>  		 * dqget()/dqput() calls.
>  		 */
> -		if (i_dquot(inode)[cnt])
> +		if (dquots[cnt])
>  			continue;
>  		init_needed = 1;
>  
> @@ -1438,8 +1444,8 @@ static void __dquot_initialize(struct inode *inode, int type)
>  		/* We could race with quotaon or dqget() could have failed */
>  		if (!got[cnt])
>  			continue;
> -		if (!i_dquot(inode)[cnt]) {
> -			i_dquot(inode)[cnt] = got[cnt];
> +		if (!dquots[cnt]) {
> +			dquots[cnt] = got[cnt];
>  			got[cnt] = NULL;
>  			/*
>  			 * Make quota reservation system happy if someone
> @@ -1447,7 +1453,7 @@ static void __dquot_initialize(struct inode *inode, int type)
>  			 */
>  			rsv = inode_get_rsv_space(inode);
>  			if (unlikely(rsv))
> -				dquot_resv_space(i_dquot(inode)[cnt], rsv);
> +				dquot_resv_space(dquots[cnt], rsv);
>  		}
>  	}
>  out_err:
> @@ -1473,12 +1479,13 @@ EXPORT_SYMBOL(dquot_initialize);
>  static void __dquot_drop(struct inode *inode)
>  {
>  	int cnt;
> +	struct dquot **dquots = i_dquot(inode);
>  	struct dquot *put[MAXQUOTAS];
>  
>  	spin_lock(&dq_data_lock);
>  	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
> -		put[cnt] = i_dquot(inode)[cnt];
> -		i_dquot(inode)[cnt] = NULL;
> +		put[cnt] = dquots[cnt];
> +		dquots[cnt] = NULL;
>  	}
>  	spin_unlock(&dq_data_lock);
>  	dqput_all(put);
> @@ -1486,6 +1493,7 @@ static void __dquot_drop(struct inode *inode)
>  
>  void dquot_drop(struct inode *inode)
>  {
> +	struct dquot * const *dquots;
>  	int cnt;
>  
>  	if (IS_NOQUOTA(inode))
> @@ -1498,8 +1506,9 @@ void dquot_drop(struct inode *inode)
>  	 * must assure that nobody can come after the DQUOT_DROP and
>  	 * add quota pointers back anyway.
>  	 */
> +	dquots = i_dquot(inode);
>  	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
> -		if (i_dquot(inode)[cnt])
> +		if (dquots[cnt])
>  			break;
>  	}
>  
> @@ -1600,8 +1609,8 @@ int __dquot_alloc_space(struct inode *inode, qsize_t number, int flags)
>  {
>  	int cnt, ret = 0, index;
>  	struct dquot_warn warn[MAXQUOTAS];
> -	struct dquot **dquots = i_dquot(inode);
>  	int reserve = flags & DQUOT_SPACE_RESERVE;
> +	struct dquot **dquots;
>  
>  	if (!dquot_active(inode)) {
>  		inode_incr_space(inode, number, reserve);
> @@ -1611,6 +1620,7 @@ int __dquot_alloc_space(struct inode *inode, qsize_t number, int flags)
>  	for (cnt = 0; cnt < MAXQUOTAS; cnt++)
>  		warn[cnt].w_type = QUOTA_NL_NOWARN;
>  
> +	dquots = i_dquot(inode);
>  	index = srcu_read_lock(&dquot_srcu);
>  	spin_lock(&dq_data_lock);
>  	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
> @@ -1652,13 +1662,14 @@ int dquot_alloc_inode(struct inode *inode)
>  {
>  	int cnt, ret = 0, index;
>  	struct dquot_warn warn[MAXQUOTAS];
> -	struct dquot * const *dquots = i_dquot(inode);
> +	struct dquot * const *dquots;
>  
>  	if (!dquot_active(inode))
>  		return 0;
>  	for (cnt = 0; cnt < MAXQUOTAS; cnt++)
>  		warn[cnt].w_type = QUOTA_NL_NOWARN;
>  
> +	dquots = i_dquot(inode);
>  	index = srcu_read_lock(&dquot_srcu);
>  	spin_lock(&dq_data_lock);
>  	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
> @@ -1690,6 +1701,7 @@ EXPORT_SYMBOL(dquot_alloc_inode);
>   */
>  int dquot_claim_space_nodirty(struct inode *inode, qsize_t number)
>  {
> +	struct dquot **dquots;
>  	int cnt, index;
>  
>  	if (!dquot_active(inode)) {
> @@ -1697,18 +1709,18 @@ int dquot_claim_space_nodirty(struct inode *inode, qsize_t number)
>  		return 0;
>  	}
>  
> +	dquots = i_dquot(inode);
>  	index = srcu_read_lock(&dquot_srcu);
>  	spin_lock(&dq_data_lock);
>  	/* Claim reserved quotas to allocated quotas */
>  	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
> -		if (i_dquot(inode)[cnt])
> -			dquot_claim_reserved_space(i_dquot(inode)[cnt],
> -							number);
> +		if (dquots[cnt])
> +			dquot_claim_reserved_space(dquots[cnt], number);
>  	}
>  	/* Update inode bytes */
>  	inode_claim_rsv_space(inode, number);
>  	spin_unlock(&dq_data_lock);
> -	mark_all_dquot_dirty(i_dquot(inode));
> +	mark_all_dquot_dirty(dquots);
>  	srcu_read_unlock(&dquot_srcu, index);
>  	return 0;
>  }
> @@ -1719,6 +1731,7 @@ EXPORT_SYMBOL(dquot_claim_space_nodirty);
>   */
>  void dquot_reclaim_space_nodirty(struct inode *inode, qsize_t number)
>  {
> +	struct dquot **dquots;
>  	int cnt, index;
>  
>  	if (!dquot_active(inode)) {
> @@ -1726,18 +1739,18 @@ void dquot_reclaim_space_nodirty(struct inode *inode, qsize_t number)
>  		return;
>  	}
>  
> +	dquots = i_dquot(inode);
>  	index = srcu_read_lock(&dquot_srcu);
>  	spin_lock(&dq_data_lock);
>  	/* Claim reserved quotas to allocated quotas */
>  	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
> -		if (i_dquot(inode)[cnt])
> -			dquot_reclaim_reserved_space(i_dquot(inode)[cnt],
> -						     number);
> +		if (dquots[cnt])
> +			dquot_reclaim_reserved_space(dquots[cnt], number);
>  	}
>  	/* Update inode bytes */
>  	inode_reclaim_rsv_space(inode, number);
>  	spin_unlock(&dq_data_lock);
> -	mark_all_dquot_dirty(i_dquot(inode));
> +	mark_all_dquot_dirty(dquots);
>  	srcu_read_unlock(&dquot_srcu, index);
>  	return;
>  }
> @@ -1750,7 +1763,7 @@ void __dquot_free_space(struct inode *inode, qsize_t number, int flags)
>  {
>  	unsigned int cnt;
>  	struct dquot_warn warn[MAXQUOTAS];
> -	struct dquot **dquots = i_dquot(inode);
> +	struct dquot **dquots;
>  	int reserve = flags & DQUOT_SPACE_RESERVE, index;
>  
>  	if (!dquot_active(inode)) {
> @@ -1758,6 +1771,7 @@ void __dquot_free_space(struct inode *inode, qsize_t number, int flags)
>  		return;
>  	}
>  
> +	dquots = i_dquot(inode);
>  	index = srcu_read_lock(&dquot_srcu);
>  	spin_lock(&dq_data_lock);
>  	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
> @@ -1793,12 +1807,13 @@ void dquot_free_inode(struct inode *inode)
>  {
>  	unsigned int cnt;
>  	struct dquot_warn warn[MAXQUOTAS];
> -	struct dquot * const *dquots = i_dquot(inode);
> +	struct dquot * const *dquots;
>  	int index;
>  
>  	if (!dquot_active(inode))
>  		return;
>  
> +	dquots = i_dquot(inode);
>  	index = srcu_read_lock(&dquot_srcu);
>  	spin_lock(&dq_data_lock);
>  	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
>
diff mbox

Patch

diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
index 0ccd4ba..2112ed3 100644
--- a/fs/quota/dquot.c
+++ b/fs/quota/dquot.c
@@ -900,14 +900,17 @@  static inline struct dquot **i_dquot(struct inode *inode)
 
 static int dqinit_needed(struct inode *inode, int type)
 {
+	struct dquot * const *dquots;
 	int cnt;
 
 	if (IS_NOQUOTA(inode))
 		return 0;
+
+	dquots = i_dquot(inode);
 	if (type != -1)
-		return !i_dquot(inode)[type];
+		return !dquots[type];
 	for (cnt = 0; cnt < MAXQUOTAS; cnt++)
-		if (!i_dquot(inode)[cnt])
+		if (!dquots[cnt])
 			return 1;
 	return 0;
 }
@@ -970,12 +973,13 @@  static void add_dquot_ref(struct super_block *sb, int type)
 static void remove_inode_dquot_ref(struct inode *inode, int type,
 				   struct list_head *tofree_head)
 {
-	struct dquot *dquot = i_dquot(inode)[type];
+	struct dquot **dquots = i_dquot(inode);
+	struct dquot *dquot = dquots[type];
 
-	i_dquot(inode)[type] = NULL;
 	if (!dquot)
 		return;
 
+	dquots[type] = NULL;
 	if (list_empty(&dquot->dq_free)) {
 		/*
 		 * The inode still has reference to dquot so it can't be in the
@@ -1389,13 +1393,15 @@  static int dquot_active(const struct inode *inode)
 static void __dquot_initialize(struct inode *inode, int type)
 {
 	int cnt, init_needed = 0;
-	struct dquot *got[MAXQUOTAS];
+	struct dquot **dquots, *got[MAXQUOTAS];
 	struct super_block *sb = inode->i_sb;
 	qsize_t rsv;
 
 	if (!dquot_active(inode))
 		return;
 
+	dquots = i_dquot(inode);
+
 	/* First get references to structures we might need. */
 	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
 		struct kqid qid;
@@ -1407,7 +1413,7 @@  static void __dquot_initialize(struct inode *inode, int type)
 		 * we check it without locking here to avoid unnecessary
 		 * dqget()/dqput() calls.
 		 */
-		if (i_dquot(inode)[cnt])
+		if (dquots[cnt])
 			continue;
 		init_needed = 1;
 
@@ -1438,8 +1444,8 @@  static void __dquot_initialize(struct inode *inode, int type)
 		/* We could race with quotaon or dqget() could have failed */
 		if (!got[cnt])
 			continue;
-		if (!i_dquot(inode)[cnt]) {
-			i_dquot(inode)[cnt] = got[cnt];
+		if (!dquots[cnt]) {
+			dquots[cnt] = got[cnt];
 			got[cnt] = NULL;
 			/*
 			 * Make quota reservation system happy if someone
@@ -1447,7 +1453,7 @@  static void __dquot_initialize(struct inode *inode, int type)
 			 */
 			rsv = inode_get_rsv_space(inode);
 			if (unlikely(rsv))
-				dquot_resv_space(i_dquot(inode)[cnt], rsv);
+				dquot_resv_space(dquots[cnt], rsv);
 		}
 	}
 out_err:
@@ -1473,12 +1479,13 @@  EXPORT_SYMBOL(dquot_initialize);
 static void __dquot_drop(struct inode *inode)
 {
 	int cnt;
+	struct dquot **dquots = i_dquot(inode);
 	struct dquot *put[MAXQUOTAS];
 
 	spin_lock(&dq_data_lock);
 	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
-		put[cnt] = i_dquot(inode)[cnt];
-		i_dquot(inode)[cnt] = NULL;
+		put[cnt] = dquots[cnt];
+		dquots[cnt] = NULL;
 	}
 	spin_unlock(&dq_data_lock);
 	dqput_all(put);
@@ -1486,6 +1493,7 @@  static void __dquot_drop(struct inode *inode)
 
 void dquot_drop(struct inode *inode)
 {
+	struct dquot * const *dquots;
 	int cnt;
 
 	if (IS_NOQUOTA(inode))
@@ -1498,8 +1506,9 @@  void dquot_drop(struct inode *inode)
 	 * must assure that nobody can come after the DQUOT_DROP and
 	 * add quota pointers back anyway.
 	 */
+	dquots = i_dquot(inode);
 	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
-		if (i_dquot(inode)[cnt])
+		if (dquots[cnt])
 			break;
 	}
 
@@ -1600,8 +1609,8 @@  int __dquot_alloc_space(struct inode *inode, qsize_t number, int flags)
 {
 	int cnt, ret = 0, index;
 	struct dquot_warn warn[MAXQUOTAS];
-	struct dquot **dquots = i_dquot(inode);
 	int reserve = flags & DQUOT_SPACE_RESERVE;
+	struct dquot **dquots;
 
 	if (!dquot_active(inode)) {
 		inode_incr_space(inode, number, reserve);
@@ -1611,6 +1620,7 @@  int __dquot_alloc_space(struct inode *inode, qsize_t number, int flags)
 	for (cnt = 0; cnt < MAXQUOTAS; cnt++)
 		warn[cnt].w_type = QUOTA_NL_NOWARN;
 
+	dquots = i_dquot(inode);
 	index = srcu_read_lock(&dquot_srcu);
 	spin_lock(&dq_data_lock);
 	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
@@ -1652,13 +1662,14 @@  int dquot_alloc_inode(struct inode *inode)
 {
 	int cnt, ret = 0, index;
 	struct dquot_warn warn[MAXQUOTAS];
-	struct dquot * const *dquots = i_dquot(inode);
+	struct dquot * const *dquots;
 
 	if (!dquot_active(inode))
 		return 0;
 	for (cnt = 0; cnt < MAXQUOTAS; cnt++)
 		warn[cnt].w_type = QUOTA_NL_NOWARN;
 
+	dquots = i_dquot(inode);
 	index = srcu_read_lock(&dquot_srcu);
 	spin_lock(&dq_data_lock);
 	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
@@ -1690,6 +1701,7 @@  EXPORT_SYMBOL(dquot_alloc_inode);
  */
 int dquot_claim_space_nodirty(struct inode *inode, qsize_t number)
 {
+	struct dquot **dquots;
 	int cnt, index;
 
 	if (!dquot_active(inode)) {
@@ -1697,18 +1709,18 @@  int dquot_claim_space_nodirty(struct inode *inode, qsize_t number)
 		return 0;
 	}
 
+	dquots = i_dquot(inode);
 	index = srcu_read_lock(&dquot_srcu);
 	spin_lock(&dq_data_lock);
 	/* Claim reserved quotas to allocated quotas */
 	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
-		if (i_dquot(inode)[cnt])
-			dquot_claim_reserved_space(i_dquot(inode)[cnt],
-							number);
+		if (dquots[cnt])
+			dquot_claim_reserved_space(dquots[cnt], number);
 	}
 	/* Update inode bytes */
 	inode_claim_rsv_space(inode, number);
 	spin_unlock(&dq_data_lock);
-	mark_all_dquot_dirty(i_dquot(inode));
+	mark_all_dquot_dirty(dquots);
 	srcu_read_unlock(&dquot_srcu, index);
 	return 0;
 }
@@ -1719,6 +1731,7 @@  EXPORT_SYMBOL(dquot_claim_space_nodirty);
  */
 void dquot_reclaim_space_nodirty(struct inode *inode, qsize_t number)
 {
+	struct dquot **dquots;
 	int cnt, index;
 
 	if (!dquot_active(inode)) {
@@ -1726,18 +1739,18 @@  void dquot_reclaim_space_nodirty(struct inode *inode, qsize_t number)
 		return;
 	}
 
+	dquots = i_dquot(inode);
 	index = srcu_read_lock(&dquot_srcu);
 	spin_lock(&dq_data_lock);
 	/* Claim reserved quotas to allocated quotas */
 	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
-		if (i_dquot(inode)[cnt])
-			dquot_reclaim_reserved_space(i_dquot(inode)[cnt],
-						     number);
+		if (dquots[cnt])
+			dquot_reclaim_reserved_space(dquots[cnt], number);
 	}
 	/* Update inode bytes */
 	inode_reclaim_rsv_space(inode, number);
 	spin_unlock(&dq_data_lock);
-	mark_all_dquot_dirty(i_dquot(inode));
+	mark_all_dquot_dirty(dquots);
 	srcu_read_unlock(&dquot_srcu, index);
 	return;
 }
@@ -1750,7 +1763,7 @@  void __dquot_free_space(struct inode *inode, qsize_t number, int flags)
 {
 	unsigned int cnt;
 	struct dquot_warn warn[MAXQUOTAS];
-	struct dquot **dquots = i_dquot(inode);
+	struct dquot **dquots;
 	int reserve = flags & DQUOT_SPACE_RESERVE, index;
 
 	if (!dquot_active(inode)) {
@@ -1758,6 +1771,7 @@  void __dquot_free_space(struct inode *inode, qsize_t number, int flags)
 		return;
 	}
 
+	dquots = i_dquot(inode);
 	index = srcu_read_lock(&dquot_srcu);
 	spin_lock(&dq_data_lock);
 	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
@@ -1793,12 +1807,13 @@  void dquot_free_inode(struct inode *inode)
 {
 	unsigned int cnt;
 	struct dquot_warn warn[MAXQUOTAS];
-	struct dquot * const *dquots = i_dquot(inode);
+	struct dquot * const *dquots;
 	int index;
 
 	if (!dquot_active(inode))
 		return;
 
+	dquots = i_dquot(inode);
 	index = srcu_read_lock(&dquot_srcu);
 	spin_lock(&dq_data_lock);
 	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {