remove libdss from Makefile
[GitHub/moto-9609/android_kernel_motorola_exynos9610.git] / mm / zsmalloc.c
index 7c38e850a8fc5ce0c4f64090e9f9ac6ef6de7203..abf1a560fa2bbb85cf30a87b19720d52dc55abba 100644 (file)
@@ -190,6 +190,7 @@ static struct vfsmount *zsmalloc_mnt;
  * (see: fix_fullness_group())
  */
 static const int fullness_threshold_frac = 4;
+static size_t huge_class_size;
 
 struct size_class {
        spinlock_t lock;
@@ -1349,7 +1350,7 @@ void *zs_map_object(struct zs_pool *pool, unsigned long handle,
         * pools/users, we can't allow mapping in interrupt context
         * because it can corrupt another users mappings.
         */
-       WARN_ON_ONCE(in_interrupt());
+       BUG_ON(in_interrupt());
 
        /* From now on, migration cannot move the object */
        pin_tag(handle);
@@ -1426,6 +1427,25 @@ void zs_unmap_object(struct zs_pool *pool, unsigned long handle)
 }
 EXPORT_SYMBOL_GPL(zs_unmap_object);
 
+/**
+ * zs_huge_class_size() - Returns the size (in bytes) of the first huge
+ *                        zsmalloc &size_class.
+ * @pool: zsmalloc pool to use
+ *
+ * The function returns the size of the first huge class - any object of equal
+ * or bigger size will be stored in zspage consisting of a single physical
+ * page.
+ *
+ * Context: Any context.
+ *
+ * Return: the size (in bytes) of the first huge zsmalloc &size_class.
+ */
+size_t zs_huge_class_size(struct zs_pool *pool)
+{
+       return huge_class_size;
+}
+EXPORT_SYMBOL_GPL(zs_huge_class_size);
+
 static unsigned long obj_malloc(struct size_class *class,
                                struct zspage *zspage, unsigned long handle)
 {
@@ -2385,6 +2405,27 @@ struct zs_pool *zs_create_pool(const char *name)
                pages_per_zspage = get_pages_per_zspage(size);
                objs_per_zspage = pages_per_zspage * PAGE_SIZE / size;
 
+               /*
+                * We iterate from biggest down to smallest classes,
+                * so huge_class_size holds the size of the first huge
+                * class. Any object bigger than or equal to that will
+                * endup in the huge class.
+                */
+               if (pages_per_zspage != 1 && objs_per_zspage != 1 &&
+                               !huge_class_size) {
+                       huge_class_size = size;
+                       /*
+                        * The object uses ZS_HANDLE_SIZE bytes to store the
+                        * handle. We need to subtract it, because zs_malloc()
+                        * unconditionally adds handle size before it performs
+                        * size class search - so object may be smaller than
+                        * huge class size, yet it still can end up in the huge
+                        * class because it grows by ZS_HANDLE_SIZE extra bytes
+                        * right before class lookup.
+                        */
+                       huge_class_size -= (ZS_HANDLE_SIZE - 1);
+               }
+
                /*
                 * size_class is used for normal zsmalloc operation such
                 * as alloc/free for that size. Although it is natural that we