]> Pileus Git - ~andy/linux/blobdiff - mm/vmpressure.c
Merge branch 'for-3.12' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup
[~andy/linux] / mm / vmpressure.c
index 13489b1f4ee3f6637cb54c47e7501099a5c5bf09..e0f62837c3f4873ea2d54c14845c30cb888a386b 100644 (file)
@@ -175,12 +175,12 @@ static void vmpressure_work_fn(struct work_struct *work)
        if (!vmpr->scanned)
                return;
 
-       mutex_lock(&vmpr->sr_lock);
+       spin_lock(&vmpr->sr_lock);
        scanned = vmpr->scanned;
        reclaimed = vmpr->reclaimed;
        vmpr->scanned = 0;
        vmpr->reclaimed = 0;
-       mutex_unlock(&vmpr->sr_lock);
+       spin_unlock(&vmpr->sr_lock);
 
        do {
                if (vmpressure_event(vmpr, scanned, reclaimed))
@@ -235,13 +235,13 @@ void vmpressure(gfp_t gfp, struct mem_cgroup *memcg,
        if (!scanned)
                return;
 
-       mutex_lock(&vmpr->sr_lock);
+       spin_lock(&vmpr->sr_lock);
        vmpr->scanned += scanned;
        vmpr->reclaimed += reclaimed;
        scanned = vmpr->scanned;
-       mutex_unlock(&vmpr->sr_lock);
+       spin_unlock(&vmpr->sr_lock);
 
-       if (scanned < vmpressure_win || work_pending(&vmpr->work))
+       if (scanned < vmpressure_win)
                return;
        schedule_work(&vmpr->work);
 }
@@ -364,8 +364,24 @@ void vmpressure_unregister_event(struct cgroup_subsys_state *css,
  */
 void vmpressure_init(struct vmpressure *vmpr)
 {
-       mutex_init(&vmpr->sr_lock);
+       spin_lock_init(&vmpr->sr_lock);
        mutex_init(&vmpr->events_lock);
        INIT_LIST_HEAD(&vmpr->events);
        INIT_WORK(&vmpr->work, vmpressure_work_fn);
 }
+
+/**
+ * vmpressure_cleanup() - shuts down vmpressure control structure
+ * @vmpr:      Structure to be cleaned up
+ *
+ * This function should be called before the structure in which it is
+ * embedded is cleaned up.
+ */
+void vmpressure_cleanup(struct vmpressure *vmpr)
+{
+       /*
+        * Make sure there is no pending work before eventfd infrastructure
+        * goes away.
+        */
+       flush_work(&vmpr->work);
+}