unsigned long dirty_limit;
 };
 
+/**
+ * wb_domain_size_changed - memory available to a wb_domain has changed
+ * @dom: wb_domain of interest
+ *
+ * This function should be called when the amount of memory available to
+ * @dom has changed.  It resets @dom's dirty limit parameters to prevent
+ * the past values which don't match the current configuration from skewing
+ * dirty throttling.  Without this, when memory size of a wb_domain is
+ * greatly reduced, the dirty throttling logic may allow too many pages to
+ * be dirtied leading to consecutive unnecessary OOMs and may get stuck in
+ * that situation.
+ */
+static inline void wb_domain_size_changed(struct wb_domain *dom)
+{
+       spin_lock(&dom->lock);
+       dom->dirty_limit_tstamp = jiffies;
+       dom->dirty_limit = 0;
+       spin_unlock(&dom->lock);
+}
+
 /*
  * fs/fs-writeback.c
  */    
 
        wb_domain_exit(&memcg->cgwb_domain);
 }
 
+static void memcg_wb_domain_size_changed(struct mem_cgroup *memcg)
+{
+       wb_domain_size_changed(&memcg->cgwb_domain);
+}
+
 struct wb_domain *mem_cgroup_wb_domain(struct bdi_writeback *wb)
 {
        struct mem_cgroup *memcg = mem_cgroup_from_css(wb->memcg_css);
 {
 }
 
+static void memcg_wb_domain_size_changed(struct mem_cgroup *memcg)
+{
+}
+
 #endif /* CONFIG_CGROUP_WRITEBACK */
 
 /*
        memcg->low = 0;
        memcg->high = PAGE_COUNTER_MAX;
        memcg->soft_limit = PAGE_COUNTER_MAX;
+       memcg_wb_domain_size_changed(memcg);
 }
 
 #ifdef CONFIG_MMU
 
        memcg->high = high;
 
+       memcg_wb_domain_size_changed(memcg);
        return nbytes;
 }
 
        if (err)
                return err;
 
+       memcg_wb_domain_size_changed(memcg);
        return nbytes;
 }