total_objects += list_lru_shrink_count(&sb->s_dentry_lru, sc);
        total_objects += list_lru_shrink_count(&sb->s_inode_lru, sc);
 
+       if (!total_objects)
+               return SHRINK_EMPTY;
+
        total_objects = vfs_pressure_ratio(total_objects);
        return total_objects;
 }
 
 };
 
 #define SHRINK_STOP (~0UL)
+#define SHRINK_EMPTY (~0UL - 1)
 /*
  * A callback you can register to apply pressure to ageable caches.
  *
  * @count_objects should return the number of freeable items in the cache. If
- * there are no objects to free or the number of freeable items cannot be
- * determined, it should return 0. No deadlock checks should be done during the
+ * there are no objects to free, it should return SHRINK_EMPTY, while 0 is
+ * returned in cases of the number of freeable items cannot be determined
+ * or shrinker should skip this cache for this time (e.g., their number
+ * is below shrinkable limit). No deadlock checks should be done during the
  * count callback - the shrinker relies on aggregating scan counts that couldn't
  * be executed due to potential deadlocks to be run at a later call when the
  * deadlock condition is no longer pending.
 
        long scanned = 0, next_deferred;
 
        freeable = shrinker->count_objects(shrinker, shrinkctl);
-       if (freeable == 0)
-               return 0;
+       if (freeable == 0 || freeable == SHRINK_EMPTY)
+               return freeable;
 
        /*
         * copy the current shrinker scan count into a local variable
                        continue;
 
                ret = do_shrink_slab(&sc, shrinker, priority);
+               if (ret == SHRINK_EMPTY)
+                       ret = 0;
                freed += ret;
 
                if (rwsem_is_contended(&shrinker_rwsem)) {
 {
        struct shrinker *shrinker;
        unsigned long freed = 0;
+       int ret;
 
        if (!mem_cgroup_is_root(memcg))
                return shrink_slab_memcg(gfp_mask, nid, memcg, priority);
                if (!(shrinker->flags & SHRINKER_NUMA_AWARE))
                        sc.nid = 0;
 
-               freed += do_shrink_slab(&sc, shrinker, priority);
+               ret = do_shrink_slab(&sc, shrinker, priority);
+               if (ret == SHRINK_EMPTY)
+                       ret = 0;
+               freed += ret;
                /*
                 * Bail out if someone want to register a new shrinker to
                 * prevent the regsitration from being stalled for long periods