diff for duplicates of <20150304050742.GA5418@blaptop> diff --git a/a/1.txt b/N1/1.txt index b416816..6f77295 100644 --- a/a/1.txt +++ b/N1/1.txt @@ -1,3 +1,347 @@ Oops. I sent old version which had a bug Ganesh pointed out. Sorry for that. Please review this instead. + +>From 2a9b47817988882ae3b1c84e0f3e53519be87caf Mon Sep 17 00:00:00 2001 +From: Minchan Kim <minchan@kernel.org> +Date: Tue, 13 Jan 2015 10:37:16 +0900 +Subject: [PATCH] zsmalloc: decouple handle and object + +Currently, handle of zsmalloc encodes object's location directly +so it makes support of migration hard. + +This patch decouples handle and object via adding indirect layer. +For that, it allocates handle dynamically and returns it to user. +The handle is the address allocated by slab allocation so it's +unique and we could keep object's location in the memory space +allocated for handle. + +With it, we can change object's position without changing handle +itself. + +Signed-off-by: Minchan Kim <minchan@kernel.org> +--- + mm/zsmalloc.c | 126 +++++++++++++++++++++++++++++++++++++++++++++------------- + 1 file changed, 98 insertions(+), 28 deletions(-) + +diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c +index 0dec1fa5f656..6f3cfbf5e237 100644 +--- a/mm/zsmalloc.c ++++ b/mm/zsmalloc.c +@@ -110,6 +110,8 @@ + #define ZS_MAX_ZSPAGE_ORDER 2 + #define ZS_MAX_PAGES_PER_ZSPAGE (_AC(1, UL) << ZS_MAX_ZSPAGE_ORDER) + ++#define ZS_HANDLE_SIZE (sizeof(unsigned long)) ++ + /* + * Object location (<PFN>, <obj_idx>) is encoded as + * as single (unsigned long) handle value. +@@ -140,7 +142,8 @@ + /* ZS_MIN_ALLOC_SIZE must be multiple of ZS_ALIGN */ + #define ZS_MIN_ALLOC_SIZE \ + MAX(32, (ZS_MAX_PAGES_PER_ZSPAGE << PAGE_SHIFT >> OBJ_INDEX_BITS)) +-#define ZS_MAX_ALLOC_SIZE PAGE_SIZE ++/* each chunk includes extra space to keep handle */ ++#define ZS_MAX_ALLOC_SIZE (PAGE_SIZE + ZS_HANDLE_SIZE) + + /* + * On systems with 4K page size, this gives 255 size classes! There is a +@@ -233,14 +236,24 @@ struct size_class { + * This must be power of 2 and less than or equal to ZS_ALIGN + */ + struct link_free { +- /* Handle of next free chunk (encodes <PFN, obj_idx>) */ +- void *next; ++ union { ++ /* ++ * Position of next free chunk (encodes <PFN, obj_idx>) ++ * It's valid for non-allocated object ++ */ ++ void *next; ++ /* ++ * Handle of allocated object. ++ */ ++ unsigned long handle; ++ }; + }; + + struct zs_pool { + char *name; + + struct size_class **size_class; ++ struct kmem_cache *handle_cachep; + + gfp_t flags; /* allocation flags used when growing pool */ + atomic_long_t pages_allocated; +@@ -269,6 +282,34 @@ struct mapping_area { + enum zs_mapmode vm_mm; /* mapping mode */ + }; + ++static int create_handle_cache(struct zs_pool *pool) ++{ ++ pool->handle_cachep = kmem_cache_create("zs_handle", ZS_HANDLE_SIZE, ++ 0, 0, NULL); ++ return pool->handle_cachep ? 0 : 1; ++} ++ ++static void destroy_handle_cache(struct zs_pool *pool) ++{ ++ kmem_cache_destroy(pool->handle_cachep); ++} ++ ++static unsigned long alloc_handle(struct zs_pool *pool) ++{ ++ return (unsigned long)kmem_cache_alloc(pool->handle_cachep, ++ pool->flags & ~__GFP_HIGHMEM); ++} ++ ++static void free_handle(struct zs_pool *pool, unsigned long handle) ++{ ++ kmem_cache_free(pool->handle_cachep, (void *)handle); ++} ++ ++static void record_obj(unsigned long handle, unsigned long obj) ++{ ++ *(unsigned long *)handle = obj; ++} ++ + /* zpool driver */ + + #ifdef CONFIG_ZPOOL +@@ -595,13 +636,18 @@ static void *obj_location_to_handle(struct page *page, unsigned long obj_idx) + * decoded obj_idx back to its original value since it was adjusted in + * obj_location_to_handle(). + */ +-static void obj_handle_to_location(unsigned long handle, struct page **page, ++static void obj_to_location(unsigned long handle, struct page **page, + unsigned long *obj_idx) + { + *page = pfn_to_page(handle >> OBJ_INDEX_BITS); + *obj_idx = (handle & OBJ_INDEX_MASK) - 1; + } + ++static unsigned long handle_to_obj(unsigned long handle) ++{ ++ return *(unsigned long *)handle; ++} ++ + static unsigned long obj_idx_to_offset(struct page *page, + unsigned long obj_idx, int class_size) + { +@@ -860,12 +906,16 @@ static void __zs_unmap_object(struct mapping_area *area, + { + int sizes[2]; + void *addr; +- char *buf = area->vm_buf; ++ char *buf; + + /* no write fastpath */ + if (area->vm_mm == ZS_MM_RO) + goto out; + ++ buf = area->vm_buf + ZS_HANDLE_SIZE; ++ size -= ZS_HANDLE_SIZE; ++ off += ZS_HANDLE_SIZE; ++ + sizes[0] = PAGE_SIZE - off; + sizes[1] = size - sizes[0]; + +@@ -1153,13 +1203,14 @@ void *zs_map_object(struct zs_pool *pool, unsigned long handle, + enum zs_mapmode mm) + { + struct page *page; +- unsigned long obj_idx, off; ++ unsigned long obj, obj_idx, off; + + unsigned int class_idx; + enum fullness_group fg; + struct size_class *class; + struct mapping_area *area; + struct page *pages[2]; ++ void *ret; + + BUG_ON(!handle); + +@@ -1170,7 +1221,8 @@ void *zs_map_object(struct zs_pool *pool, unsigned long handle, + */ + BUG_ON(in_interrupt()); + +- obj_handle_to_location(handle, &page, &obj_idx); ++ obj = handle_to_obj(handle); ++ obj_to_location(obj, &page, &obj_idx); + get_zspage_mapping(get_first_page(page), &class_idx, &fg); + class = pool->size_class[class_idx]; + off = obj_idx_to_offset(page, obj_idx, class->size); +@@ -1180,7 +1232,8 @@ void *zs_map_object(struct zs_pool *pool, unsigned long handle, + if (off + class->size <= PAGE_SIZE) { + /* this object is contained entirely within a page */ + area->vm_addr = kmap_atomic(page); +- return area->vm_addr + off; ++ ret = area->vm_addr + off; ++ goto out; + } + + /* this object spans two pages */ +@@ -1188,14 +1241,16 @@ void *zs_map_object(struct zs_pool *pool, unsigned long handle, + pages[1] = get_next_page(page); + BUG_ON(!pages[1]); + +- return __zs_map_object(area, pages, off, class->size); ++ ret = __zs_map_object(area, pages, off, class->size); ++out: ++ return ret + ZS_HANDLE_SIZE; + } + EXPORT_SYMBOL_GPL(zs_map_object); + + void zs_unmap_object(struct zs_pool *pool, unsigned long handle) + { + struct page *page; +- unsigned long obj_idx, off; ++ unsigned long obj, obj_idx, off; + + unsigned int class_idx; + enum fullness_group fg; +@@ -1204,7 +1259,8 @@ void zs_unmap_object(struct zs_pool *pool, unsigned long handle) + + BUG_ON(!handle); + +- obj_handle_to_location(handle, &page, &obj_idx); ++ obj = handle_to_obj(handle); ++ obj_to_location(obj, &page, &obj_idx); + get_zspage_mapping(get_first_page(page), &class_idx, &fg); + class = pool->size_class[class_idx]; + off = obj_idx_to_offset(page, obj_idx, class->size); +@@ -1236,7 +1292,7 @@ EXPORT_SYMBOL_GPL(zs_unmap_object); + */ + unsigned long zs_malloc(struct zs_pool *pool, size_t size) + { +- unsigned long obj; ++ unsigned long handle, obj; + struct link_free *link; + struct size_class *class; + void *vaddr; +@@ -1244,9 +1300,15 @@ unsigned long zs_malloc(struct zs_pool *pool, size_t size) + struct page *first_page, *m_page; + unsigned long m_objidx, m_offset; + +- if (unlikely(!size || size > ZS_MAX_ALLOC_SIZE)) ++ if (unlikely(!size || (size + ZS_HANDLE_SIZE) > ZS_MAX_ALLOC_SIZE)) ++ return 0; ++ ++ handle = alloc_handle(pool); ++ if (!handle) + return 0; + ++ /* extra space in chunk to keep the handle */ ++ size += ZS_HANDLE_SIZE; + class = pool->size_class[get_size_class_index(size)]; + + spin_lock(&class->lock); +@@ -1255,8 +1317,10 @@ unsigned long zs_malloc(struct zs_pool *pool, size_t size) + if (!first_page) { + spin_unlock(&class->lock); + first_page = alloc_zspage(class, pool->flags); +- if (unlikely(!first_page)) ++ if (unlikely(!first_page)) { ++ free_handle(pool, handle); + return 0; ++ } + + set_zspage_mapping(first_page, class->index, ZS_EMPTY); + atomic_long_add(class->pages_per_zspage, +@@ -1268,40 +1332,45 @@ unsigned long zs_malloc(struct zs_pool *pool, size_t size) + } + + obj = (unsigned long)first_page->freelist; +- obj_handle_to_location(obj, &m_page, &m_objidx); ++ obj_to_location(obj, &m_page, &m_objidx); + m_offset = obj_idx_to_offset(m_page, m_objidx, class->size); + + vaddr = kmap_atomic(m_page); + link = (struct link_free *)vaddr + m_offset / sizeof(*link); + first_page->freelist = link->next; +- memset(link, POISON_INUSE, sizeof(*link)); ++ ++ /* record handle in the header of allocated chunk */ ++ link->handle = handle; + kunmap_atomic(vaddr); + + first_page->inuse++; + zs_stat_inc(class, OBJ_USED, 1); + /* Now move the zspage to another fullness group, if required */ + fix_fullness_group(pool, first_page); ++ record_obj(handle, obj); + spin_unlock(&class->lock); + +- return obj; ++ return handle; + } + EXPORT_SYMBOL_GPL(zs_malloc); + +-void zs_free(struct zs_pool *pool, unsigned long obj) ++void zs_free(struct zs_pool *pool, unsigned long handle) + { + struct link_free *link; + struct page *first_page, *f_page; +- unsigned long f_objidx, f_offset; ++ unsigned long obj, f_objidx, f_offset; + void *vaddr; + + int class_idx; + struct size_class *class; + enum fullness_group fullness; + +- if (unlikely(!obj)) ++ if (unlikely(!handle)) + return; + +- obj_handle_to_location(obj, &f_page, &f_objidx); ++ obj = handle_to_obj(handle); ++ free_handle(pool, handle); ++ obj_to_location(obj, &f_page, &f_objidx); + first_page = get_first_page(f_page); + + get_zspage_mapping(first_page, &class_idx, &fullness); +@@ -1355,20 +1424,20 @@ struct zs_pool *zs_create_pool(char *name, gfp_t flags) + if (!pool) + return NULL; + +- pool->name = kstrdup(name, GFP_KERNEL); +- if (!pool->name) { +- kfree(pool); +- return NULL; +- } +- + pool->size_class = kcalloc(zs_size_classes, sizeof(struct size_class *), + GFP_KERNEL); + if (!pool->size_class) { +- kfree(pool->name); + kfree(pool); + return NULL; + } + ++ pool->name = kstrdup(name, GFP_KERNEL); ++ if (!pool->name) ++ goto err; ++ ++ if (create_handle_cache(pool)) ++ goto err; ++ + /* + * Iterate reversly, because, size of size_class that we want to use + * for merging should be larger or equal to current size. +@@ -1450,6 +1519,7 @@ void zs_destroy_pool(struct zs_pool *pool) + kfree(class); + } + ++ destroy_handle_cache(pool); + kfree(pool->size_class); + kfree(pool->name); + kfree(pool); +-- +1.9.1 + +-- +Kind regards, +Minchan Kim diff --git a/a/content_digest b/N1/content_digest index 7297c23..411711b 100644 --- a/a/content_digest +++ b/N1/content_digest @@ -20,6 +20,350 @@ "b\0" "Oops. I sent old version which had a bug Ganesh pointed out.\n" "Sorry for that.\n" - Please review this instead. + "Please review this instead.\n" + "\n" + ">From 2a9b47817988882ae3b1c84e0f3e53519be87caf Mon Sep 17 00:00:00 2001\n" + "From: Minchan Kim <minchan@kernel.org>\n" + "Date: Tue, 13 Jan 2015 10:37:16 +0900\n" + "Subject: [PATCH] zsmalloc: decouple handle and object\n" + "\n" + "Currently, handle of zsmalloc encodes object's location directly\n" + "so it makes support of migration hard.\n" + "\n" + "This patch decouples handle and object via adding indirect layer.\n" + "For that, it allocates handle dynamically and returns it to user.\n" + "The handle is the address allocated by slab allocation so it's\n" + "unique and we could keep object's location in the memory space\n" + "allocated for handle.\n" + "\n" + "With it, we can change object's position without changing handle\n" + "itself.\n" + "\n" + "Signed-off-by: Minchan Kim <minchan@kernel.org>\n" + "---\n" + " mm/zsmalloc.c | 126 +++++++++++++++++++++++++++++++++++++++++++++-------------\n" + " 1 file changed, 98 insertions(+), 28 deletions(-)\n" + "\n" + "diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c\n" + "index 0dec1fa5f656..6f3cfbf5e237 100644\n" + "--- a/mm/zsmalloc.c\n" + "+++ b/mm/zsmalloc.c\n" + "@@ -110,6 +110,8 @@\n" + " #define ZS_MAX_ZSPAGE_ORDER 2\n" + " #define ZS_MAX_PAGES_PER_ZSPAGE (_AC(1, UL) << ZS_MAX_ZSPAGE_ORDER)\n" + " \n" + "+#define ZS_HANDLE_SIZE (sizeof(unsigned long))\n" + "+\n" + " /*\n" + " * Object location (<PFN>, <obj_idx>) is encoded as\n" + " * as single (unsigned long) handle value.\n" + "@@ -140,7 +142,8 @@\n" + " /* ZS_MIN_ALLOC_SIZE must be multiple of ZS_ALIGN */\n" + " #define ZS_MIN_ALLOC_SIZE \\\n" + " \tMAX(32, (ZS_MAX_PAGES_PER_ZSPAGE << PAGE_SHIFT >> OBJ_INDEX_BITS))\n" + "-#define ZS_MAX_ALLOC_SIZE\tPAGE_SIZE\n" + "+/* each chunk includes extra space to keep handle */\n" + "+#define ZS_MAX_ALLOC_SIZE\t(PAGE_SIZE + ZS_HANDLE_SIZE)\n" + " \n" + " /*\n" + " * On systems with 4K page size, this gives 255 size classes! There is a\n" + "@@ -233,14 +236,24 @@ struct size_class {\n" + " * This must be power of 2 and less than or equal to ZS_ALIGN\n" + " */\n" + " struct link_free {\n" + "-\t/* Handle of next free chunk (encodes <PFN, obj_idx>) */\n" + "-\tvoid *next;\n" + "+\tunion {\n" + "+\t\t/*\n" + "+\t\t * Position of next free chunk (encodes <PFN, obj_idx>)\n" + "+\t\t * It's valid for non-allocated object\n" + "+\t\t */\n" + "+\t\tvoid *next;\n" + "+\t\t/*\n" + "+\t\t * Handle of allocated object.\n" + "+\t\t */\n" + "+\t\tunsigned long handle;\n" + "+\t};\n" + " };\n" + " \n" + " struct zs_pool {\n" + " \tchar *name;\n" + " \n" + " \tstruct size_class **size_class;\n" + "+\tstruct kmem_cache *handle_cachep;\n" + " \n" + " \tgfp_t flags;\t/* allocation flags used when growing pool */\n" + " \tatomic_long_t pages_allocated;\n" + "@@ -269,6 +282,34 @@ struct mapping_area {\n" + " \tenum zs_mapmode vm_mm; /* mapping mode */\n" + " };\n" + " \n" + "+static int create_handle_cache(struct zs_pool *pool)\n" + "+{\n" + "+\tpool->handle_cachep = kmem_cache_create(\"zs_handle\", ZS_HANDLE_SIZE,\n" + "+\t\t\t\t\t0, 0, NULL);\n" + "+\treturn pool->handle_cachep ? 0 : 1;\n" + "+}\n" + "+\n" + "+static void destroy_handle_cache(struct zs_pool *pool)\n" + "+{\n" + "+\tkmem_cache_destroy(pool->handle_cachep);\n" + "+}\n" + "+\n" + "+static unsigned long alloc_handle(struct zs_pool *pool)\n" + "+{\n" + "+\treturn (unsigned long)kmem_cache_alloc(pool->handle_cachep,\n" + "+\t\tpool->flags & ~__GFP_HIGHMEM);\n" + "+}\n" + "+\n" + "+static void free_handle(struct zs_pool *pool, unsigned long handle)\n" + "+{\n" + "+\tkmem_cache_free(pool->handle_cachep, (void *)handle);\n" + "+}\n" + "+\n" + "+static void record_obj(unsigned long handle, unsigned long obj)\n" + "+{\n" + "+\t*(unsigned long *)handle = obj;\n" + "+}\n" + "+\n" + " /* zpool driver */\n" + " \n" + " #ifdef CONFIG_ZPOOL\n" + "@@ -595,13 +636,18 @@ static void *obj_location_to_handle(struct page *page, unsigned long obj_idx)\n" + " * decoded obj_idx back to its original value since it was adjusted in\n" + " * obj_location_to_handle().\n" + " */\n" + "-static void obj_handle_to_location(unsigned long handle, struct page **page,\n" + "+static void obj_to_location(unsigned long handle, struct page **page,\n" + " \t\t\t\tunsigned long *obj_idx)\n" + " {\n" + " \t*page = pfn_to_page(handle >> OBJ_INDEX_BITS);\n" + " \t*obj_idx = (handle & OBJ_INDEX_MASK) - 1;\n" + " }\n" + " \n" + "+static unsigned long handle_to_obj(unsigned long handle)\n" + "+{\n" + "+\treturn *(unsigned long *)handle;\n" + "+}\n" + "+\n" + " static unsigned long obj_idx_to_offset(struct page *page,\n" + " \t\t\t\tunsigned long obj_idx, int class_size)\n" + " {\n" + "@@ -860,12 +906,16 @@ static void __zs_unmap_object(struct mapping_area *area,\n" + " {\n" + " \tint sizes[2];\n" + " \tvoid *addr;\n" + "-\tchar *buf = area->vm_buf;\n" + "+\tchar *buf;\n" + " \n" + " \t/* no write fastpath */\n" + " \tif (area->vm_mm == ZS_MM_RO)\n" + " \t\tgoto out;\n" + " \n" + "+\tbuf = area->vm_buf + ZS_HANDLE_SIZE;\n" + "+\tsize -= ZS_HANDLE_SIZE;\n" + "+\toff += ZS_HANDLE_SIZE;\n" + "+\n" + " \tsizes[0] = PAGE_SIZE - off;\n" + " \tsizes[1] = size - sizes[0];\n" + " \n" + "@@ -1153,13 +1203,14 @@ void *zs_map_object(struct zs_pool *pool, unsigned long handle,\n" + " \t\t\tenum zs_mapmode mm)\n" + " {\n" + " \tstruct page *page;\n" + "-\tunsigned long obj_idx, off;\n" + "+\tunsigned long obj, obj_idx, off;\n" + " \n" + " \tunsigned int class_idx;\n" + " \tenum fullness_group fg;\n" + " \tstruct size_class *class;\n" + " \tstruct mapping_area *area;\n" + " \tstruct page *pages[2];\n" + "+\tvoid *ret;\n" + " \n" + " \tBUG_ON(!handle);\n" + " \n" + "@@ -1170,7 +1221,8 @@ void *zs_map_object(struct zs_pool *pool, unsigned long handle,\n" + " \t */\n" + " \tBUG_ON(in_interrupt());\n" + " \n" + "-\tobj_handle_to_location(handle, &page, &obj_idx);\n" + "+\tobj = handle_to_obj(handle);\n" + "+\tobj_to_location(obj, &page, &obj_idx);\n" + " \tget_zspage_mapping(get_first_page(page), &class_idx, &fg);\n" + " \tclass = pool->size_class[class_idx];\n" + " \toff = obj_idx_to_offset(page, obj_idx, class->size);\n" + "@@ -1180,7 +1232,8 @@ void *zs_map_object(struct zs_pool *pool, unsigned long handle,\n" + " \tif (off + class->size <= PAGE_SIZE) {\n" + " \t\t/* this object is contained entirely within a page */\n" + " \t\tarea->vm_addr = kmap_atomic(page);\n" + "-\t\treturn area->vm_addr + off;\n" + "+\t\tret = area->vm_addr + off;\n" + "+\t\tgoto out;\n" + " \t}\n" + " \n" + " \t/* this object spans two pages */\n" + "@@ -1188,14 +1241,16 @@ void *zs_map_object(struct zs_pool *pool, unsigned long handle,\n" + " \tpages[1] = get_next_page(page);\n" + " \tBUG_ON(!pages[1]);\n" + " \n" + "-\treturn __zs_map_object(area, pages, off, class->size);\n" + "+\tret = __zs_map_object(area, pages, off, class->size);\n" + "+out:\n" + "+\treturn ret + ZS_HANDLE_SIZE;\n" + " }\n" + " EXPORT_SYMBOL_GPL(zs_map_object);\n" + " \n" + " void zs_unmap_object(struct zs_pool *pool, unsigned long handle)\n" + " {\n" + " \tstruct page *page;\n" + "-\tunsigned long obj_idx, off;\n" + "+\tunsigned long obj, obj_idx, off;\n" + " \n" + " \tunsigned int class_idx;\n" + " \tenum fullness_group fg;\n" + "@@ -1204,7 +1259,8 @@ void zs_unmap_object(struct zs_pool *pool, unsigned long handle)\n" + " \n" + " \tBUG_ON(!handle);\n" + " \n" + "-\tobj_handle_to_location(handle, &page, &obj_idx);\n" + "+\tobj = handle_to_obj(handle);\n" + "+\tobj_to_location(obj, &page, &obj_idx);\n" + " \tget_zspage_mapping(get_first_page(page), &class_idx, &fg);\n" + " \tclass = pool->size_class[class_idx];\n" + " \toff = obj_idx_to_offset(page, obj_idx, class->size);\n" + "@@ -1236,7 +1292,7 @@ EXPORT_SYMBOL_GPL(zs_unmap_object);\n" + " */\n" + " unsigned long zs_malloc(struct zs_pool *pool, size_t size)\n" + " {\n" + "-\tunsigned long obj;\n" + "+\tunsigned long handle, obj;\n" + " \tstruct link_free *link;\n" + " \tstruct size_class *class;\n" + " \tvoid *vaddr;\n" + "@@ -1244,9 +1300,15 @@ unsigned long zs_malloc(struct zs_pool *pool, size_t size)\n" + " \tstruct page *first_page, *m_page;\n" + " \tunsigned long m_objidx, m_offset;\n" + " \n" + "-\tif (unlikely(!size || size > ZS_MAX_ALLOC_SIZE))\n" + "+\tif (unlikely(!size || (size + ZS_HANDLE_SIZE) > ZS_MAX_ALLOC_SIZE))\n" + "+\t\treturn 0;\n" + "+\n" + "+\thandle = alloc_handle(pool);\n" + "+\tif (!handle)\n" + " \t\treturn 0;\n" + " \n" + "+\t/* extra space in chunk to keep the handle */\n" + "+\tsize += ZS_HANDLE_SIZE;\n" + " \tclass = pool->size_class[get_size_class_index(size)];\n" + " \n" + " \tspin_lock(&class->lock);\n" + "@@ -1255,8 +1317,10 @@ unsigned long zs_malloc(struct zs_pool *pool, size_t size)\n" + " \tif (!first_page) {\n" + " \t\tspin_unlock(&class->lock);\n" + " \t\tfirst_page = alloc_zspage(class, pool->flags);\n" + "-\t\tif (unlikely(!first_page))\n" + "+\t\tif (unlikely(!first_page)) {\n" + "+\t\t\tfree_handle(pool, handle);\n" + " \t\t\treturn 0;\n" + "+\t\t}\n" + " \n" + " \t\tset_zspage_mapping(first_page, class->index, ZS_EMPTY);\n" + " \t\tatomic_long_add(class->pages_per_zspage,\n" + "@@ -1268,40 +1332,45 @@ unsigned long zs_malloc(struct zs_pool *pool, size_t size)\n" + " \t}\n" + " \n" + " \tobj = (unsigned long)first_page->freelist;\n" + "-\tobj_handle_to_location(obj, &m_page, &m_objidx);\n" + "+\tobj_to_location(obj, &m_page, &m_objidx);\n" + " \tm_offset = obj_idx_to_offset(m_page, m_objidx, class->size);\n" + " \n" + " \tvaddr = kmap_atomic(m_page);\n" + " \tlink = (struct link_free *)vaddr + m_offset / sizeof(*link);\n" + " \tfirst_page->freelist = link->next;\n" + "-\tmemset(link, POISON_INUSE, sizeof(*link));\n" + "+\n" + "+\t/* record handle in the header of allocated chunk */\n" + "+\tlink->handle = handle;\n" + " \tkunmap_atomic(vaddr);\n" + " \n" + " \tfirst_page->inuse++;\n" + " \tzs_stat_inc(class, OBJ_USED, 1);\n" + " \t/* Now move the zspage to another fullness group, if required */\n" + " \tfix_fullness_group(pool, first_page);\n" + "+\trecord_obj(handle, obj);\n" + " \tspin_unlock(&class->lock);\n" + " \n" + "-\treturn obj;\n" + "+\treturn handle;\n" + " }\n" + " EXPORT_SYMBOL_GPL(zs_malloc);\n" + " \n" + "-void zs_free(struct zs_pool *pool, unsigned long obj)\n" + "+void zs_free(struct zs_pool *pool, unsigned long handle)\n" + " {\n" + " \tstruct link_free *link;\n" + " \tstruct page *first_page, *f_page;\n" + "-\tunsigned long f_objidx, f_offset;\n" + "+\tunsigned long obj, f_objidx, f_offset;\n" + " \tvoid *vaddr;\n" + " \n" + " \tint class_idx;\n" + " \tstruct size_class *class;\n" + " \tenum fullness_group fullness;\n" + " \n" + "-\tif (unlikely(!obj))\n" + "+\tif (unlikely(!handle))\n" + " \t\treturn;\n" + " \n" + "-\tobj_handle_to_location(obj, &f_page, &f_objidx);\n" + "+\tobj = handle_to_obj(handle);\n" + "+\tfree_handle(pool, handle);\n" + "+\tobj_to_location(obj, &f_page, &f_objidx);\n" + " \tfirst_page = get_first_page(f_page);\n" + " \n" + " \tget_zspage_mapping(first_page, &class_idx, &fullness);\n" + "@@ -1355,20 +1424,20 @@ struct zs_pool *zs_create_pool(char *name, gfp_t flags)\n" + " \tif (!pool)\n" + " \t\treturn NULL;\n" + " \n" + "-\tpool->name = kstrdup(name, GFP_KERNEL);\n" + "-\tif (!pool->name) {\n" + "-\t\tkfree(pool);\n" + "-\t\treturn NULL;\n" + "-\t}\n" + "-\n" + " \tpool->size_class = kcalloc(zs_size_classes, sizeof(struct size_class *),\n" + " \t\t\tGFP_KERNEL);\n" + " \tif (!pool->size_class) {\n" + "-\t\tkfree(pool->name);\n" + " \t\tkfree(pool);\n" + " \t\treturn NULL;\n" + " \t}\n" + " \n" + "+\tpool->name = kstrdup(name, GFP_KERNEL);\n" + "+\tif (!pool->name)\n" + "+\t\tgoto err;\n" + "+\n" + "+\tif (create_handle_cache(pool))\n" + "+\t\tgoto err;\n" + "+\n" + " \t/*\n" + " \t * Iterate reversly, because, size of size_class that we want to use\n" + " \t * for merging should be larger or equal to current size.\n" + "@@ -1450,6 +1519,7 @@ void zs_destroy_pool(struct zs_pool *pool)\n" + " \t\tkfree(class);\n" + " \t}\n" + " \n" + "+\tdestroy_handle_cache(pool);\n" + " \tkfree(pool->size_class);\n" + " \tkfree(pool->name);\n" + " \tkfree(pool);\n" + "-- \n" + "1.9.1\n" + "\n" + "-- \n" + "Kind regards,\n" + Minchan Kim -530ee90588f6cd2a722faf564563385c77e425736fc77996a65c22e8451190a5 +09aa70b0356843704a292ebf2cf91626d12ebb43df76e06959eda1cdafeb21a9
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.