Whamcloud - gitweb
LU-3305 quota: avoid unnecessary dqget/dqput calls 40/6440/5
authorNiu Yawei <yawei.niu@intel.com>
Fri, 24 May 2013 03:49:03 +0000 (23:49 -0400)
committerOleg Drokin <oleg.drokin@intel.com>
Wed, 10 Jul 2013 04:12:33 +0000 (04:12 +0000)
Because of the global lock contention inside the dqget()/dqput(),
we'd try to avoid dqget()/dqput() calls in dquot_initialize().

Signed-off-by: Niu Yawei <yawei.niu@intel.com>
Change-Id: I4335d880f3b912f3de70816a9bd87841605f8907
Reviewed-on: http://review.whamcloud.com/6440
Reviewed-by: Lai Siyao <lai.siyao@intel.com>
Tested-by: Hudson
Tested-by: Maloo <whamcloud.maloo@gmail.com>
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
lustre/kernel_patches/patches/quota-avoid-dqget-calls.patch [new file with mode: 0644]
lustre/kernel_patches/patches/quota-replace-dqptr-sem.patch [moved from lustre/kernel_patches/patches/replace_dqptr_sem.patch with 100% similarity]
lustre/kernel_patches/series/2.6-rhel6.series

diff --git a/lustre/kernel_patches/patches/quota-avoid-dqget-calls.patch b/lustre/kernel_patches/patches/quota-avoid-dqget-calls.patch
new file mode 100644 (file)
index 0000000..83d0272
--- /dev/null
@@ -0,0 +1,58 @@
+Index: linux-2.6.32-358.0.1.el6/fs/quota/dquot.c
+===================================================================
+--- linux-2.6.32-358.0.1.el6.orig/fs/quota/dquot.c
++++ linux-2.6.32-358.0.1.el6/fs/quota/dquot.c
+@@ -1230,7 +1230,7 @@ static int info_bdq_free(struct dquot *d
+ int dquot_initialize(struct inode *inode, int type)
+ {
+       unsigned int id = 0;
+-      int cnt, ret = 0;
++      int cnt, ret = 0, dq_get = 0;
+       struct dquot *got[MAXQUOTAS] = { NULL, NULL };
+       struct super_block *sb = inode->i_sb;
+       qsize_t rsv;
+@@ -1240,7 +1240,14 @@ int dquot_initialize(struct inode *inode
+       if (IS_NOQUOTA(inode))
+               return 0;
+-      /* First get references to structures we might need. */
++      /* In most case, the i_dquot should have been initialized, except
++       * the newly allocated one. We'd always try to skip the dqget() and
++       * dqput() calls to avoid unnecessary global lock contention. */
++      if (!(inode->i_state & I_NEW))
++              goto init_idquot;
++
++get_dquots:
++      dq_get = 1;
+       for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
+               if (type != -1 && cnt != type)
+                       continue;
+@@ -1254,7 +1261,7 @@ int dquot_initialize(struct inode *inode
+               }
+               got[cnt] = dqget(sb, id, cnt);
+       }
+-
++init_idquot:
+       spin_lock(&inode->i_lock);
+       if (IS_NOQUOTA(inode))
+               goto out_err;
+@@ -1265,6 +1272,10 @@ int dquot_initialize(struct inode *inode
+               if (!sb_has_quota_active(sb, cnt))
+                       continue;
+               if (!inode->i_dquot[cnt]) {
++                      if (dq_get == 0) {
++                              spin_unlock(&inode->i_lock);
++                              goto get_dquots;
++                      }
+                       inode->i_dquot[cnt] = got[cnt];
+                       got[cnt] = NULL;
+                       /*
+@@ -1272,7 +1283,7 @@ int dquot_initialize(struct inode *inode
+                        * did a write before quota was turned on
+                        */
+                       rsv = inode_get_rsv_space(inode);
+-                      if (unlikely(rsv)) {
++                      if (unlikely(rsv) && likely(inode->i_dquot[cnt])) {
+                               spin_lock(&dq_data_lock);
+                               dquot_resv_space(inode->i_dquot[cnt], rsv);
+                               spin_unlock(&dq_data_lock);
index 41ed3af..0f8e3b3 100644 (file)
@@ -6,4 +6,5 @@ blkdev_tunables-2.6-rhel6.patch
 export-2.6.32-vanilla.patch
 jbd2-jcberr-2.6-rhel6.patch
 bh_lru_size_config.patch
 export-2.6.32-vanilla.patch
 jbd2-jcberr-2.6-rhel6.patch
 bh_lru_size_config.patch
-replace_dqptr_sem.patch
+quota-replace-dqptr-sem.patch
+quota-avoid-dqget-calls.patch