These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / fs / gfs2 / rgrp.c
index 6af2396..c134c04 100644 (file)
@@ -729,9 +729,9 @@ void gfs2_clear_rgrpd(struct gfs2_sbd *sdp)
                rb_erase(n, &sdp->sd_rindex_tree);
 
                if (gl) {
-                       spin_lock(&gl->gl_spin);
+                       spin_lock(&gl->gl_lockref.lock);
                        gl->gl_object = NULL;
-                       spin_unlock(&gl->gl_spin);
+                       spin_unlock(&gl->gl_lockref.lock);
                        gfs2_glock_add_to_lru(gl);
                        gfs2_glock_put(gl);
                }
@@ -933,8 +933,9 @@ static int read_rindex_entry(struct gfs2_inode *ip)
                goto fail;
 
        rgd->rd_gl->gl_object = rgd;
-       rgd->rd_gl->gl_vm.start = rgd->rd_addr * bsize;
-       rgd->rd_gl->gl_vm.end = rgd->rd_gl->gl_vm.start + (rgd->rd_length * bsize) - 1;
+       rgd->rd_gl->gl_vm.start = (rgd->rd_addr * bsize) & PAGE_CACHE_MASK;
+       rgd->rd_gl->gl_vm.end = PAGE_CACHE_ALIGN((rgd->rd_addr +
+                                                 rgd->rd_length) * bsize) - 1;
        rgd->rd_rgl = (struct gfs2_rgrp_lvb *)rgd->rd_gl->gl_lksb.sb_lvbptr;
        rgd->rd_flags &= ~(GFS2_RDF_UPTODATE | GFS2_RDF_PREFERRED);
        if (rgd->rd_data > sdp->sd_max_rg_data)
@@ -978,10 +979,10 @@ static void set_rgrp_preferences(struct gfs2_sbd *sdp)
                rgd->rd_flags |= GFS2_RDF_PREFERRED;
                for (i = 0; i < sdp->sd_journals; i++) {
                        rgd = gfs2_rgrpd_get_next(rgd);
-                       if (rgd == first)
+                       if (!rgd || rgd == first)
                                break;
                }
-       } while (rgd != first);
+       } while (rgd && rgd != first);
 }
 
 /**
@@ -1244,14 +1245,13 @@ int gfs2_rgrp_go_lock(struct gfs2_holder *gh)
 }
 
 /**
- * gfs2_rgrp_go_unlock - Release RG bitmaps read in with gfs2_rgrp_bh_get()
- * @gh: The glock holder for the resource group
+ * gfs2_rgrp_brelse - Release RG bitmaps read in with gfs2_rgrp_bh_get()
+ * @rgd: The resource group
  *
  */
 
-void gfs2_rgrp_go_unlock(struct gfs2_holder *gh)
+void gfs2_rgrp_brelse(struct gfs2_rgrpd *rgd)
 {
-       struct gfs2_rgrpd *rgd = gh->gh_gl->gl_object;
        int x, length = rgd->rd_length;
 
        for (x = 0; x < length; x++) {
@@ -1264,6 +1264,22 @@ void gfs2_rgrp_go_unlock(struct gfs2_holder *gh)
 
 }
 
+/**
+ * gfs2_rgrp_go_unlock - Unlock a rgrp glock
+ * @gh: The glock holder for the resource group
+ *
+ */
+
+void gfs2_rgrp_go_unlock(struct gfs2_holder *gh)
+{
+       struct gfs2_rgrpd *rgd = gh->gh_gl->gl_object;
+       int demote_requested = test_bit(GLF_DEMOTE, &gh->gh_gl->gl_flags) |
+               test_bit(GLF_PENDING_DEMOTE, &gh->gh_gl->gl_flags);
+
+       if (rgd && demote_requested)
+               gfs2_rgrp_brelse(rgd);
+}
+
 int gfs2_rgrp_send_discards(struct gfs2_sbd *sdp, u64 offset,
                             struct buffer_head *bh,
                             const struct gfs2_bitmap *bi, unsigned minlen, u64 *ptrimmed)
@@ -1711,10 +1727,8 @@ static int gfs2_rbm_find(struct gfs2_rbm *rbm, u8 state, u32 *minext,
                return ret;
 
 bitmap_full:   /* Mark bitmap as full and fall through */
-               if ((state == GFS2_BLKST_FREE) && initial_offset == 0) {
-                       struct gfs2_bitmap *bi = rbm_bi(rbm);
+               if ((state == GFS2_BLKST_FREE) && initial_offset == 0)
                        set_bit(GBF_FULL, &bi->bi_flags);
-               }
 
 next_bitmap:   /* Find next bitmap in the rgrp */
                rbm->offset = 0;
@@ -1847,17 +1861,26 @@ static void try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked, u64 skip
 static bool gfs2_rgrp_congested(const struct gfs2_rgrpd *rgd, int loops)
 {
        const struct gfs2_glock *gl = rgd->rd_gl;
-       const struct gfs2_sbd *sdp = gl->gl_sbd;
+       const struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
        struct gfs2_lkstats *st;
-       s64 r_dcount, l_dcount;
-       s64 r_srttb, l_srttb;
+       u64 r_dcount, l_dcount;
+       u64 l_srttb, a_srttb = 0;
        s64 srttb_diff;
-       s64 sqr_diff;
-       s64 var;
+       u64 sqr_diff;
+       u64 var;
+       int cpu, nonzero = 0;
 
        preempt_disable();
+       for_each_present_cpu(cpu) {
+               st = &per_cpu_ptr(sdp->sd_lkstats, cpu)->lkstats[LM_TYPE_RGRP];
+               if (st->stats[GFS2_LKS_SRTTB]) {
+                       a_srttb += st->stats[GFS2_LKS_SRTTB];
+                       nonzero++;
+               }
+       }
        st = &this_cpu_ptr(sdp->sd_lkstats)->lkstats[LM_TYPE_RGRP];
-       r_srttb = st->stats[GFS2_LKS_SRTTB];
+       if (nonzero)
+               do_div(a_srttb, nonzero);
        r_dcount = st->stats[GFS2_LKS_DCOUNT];
        var = st->stats[GFS2_LKS_SRTTVARB] +
              gl->gl_stats.stats[GFS2_LKS_SRTTVARB];
@@ -1866,10 +1889,10 @@ static bool gfs2_rgrp_congested(const struct gfs2_rgrpd *rgd, int loops)
        l_srttb = gl->gl_stats.stats[GFS2_LKS_SRTTB];
        l_dcount = gl->gl_stats.stats[GFS2_LKS_DCOUNT];
 
-       if ((l_dcount < 1) || (r_dcount < 1) || (r_srttb == 0))
+       if ((l_dcount < 1) || (r_dcount < 1) || (a_srttb == 0))
                return false;
 
-       srttb_diff = r_srttb - l_srttb;
+       srttb_diff = a_srttb - l_srttb;
        sqr_diff = srttb_diff * srttb_diff;
 
        var *= 2;