All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCHv2 0/3] zsmalloc: small compaction improvements
@ 2023-06-24  5:12 Sergey Senozhatsky
  2023-06-24  5:12 ` [PATCHv2 1/3] zsmalloc: do not scan for allocated objects in empty zspage Sergey Senozhatsky
                   ` (3 more replies)
  0 siblings, 4 replies; 12+ messages in thread
From: Sergey Senozhatsky @ 2023-06-24  5:12 UTC (permalink / raw)
  To: Andrew Morton, Minchan Kim; +Cc: linux-mm, linux-kernel, Sergey Senozhatsky

Hi,
	A tiny series that can reduce the number of
find_alloced_obj() invocations (which perform a linear
scan of sub-page) during compaction. Inspired by Alexey
Romanov's findings.

v2:
-- picked up a patch from Minchan

Minchan Kim (1):
  zsmalloc: remove zs_compact_control

Sergey Senozhatsky (2):
  zsmalloc: do not scan for allocated objects in empty zspage
  zsmalloc: move migration destination zspage inuse check

 mm/zsmalloc.c | 50 ++++++++++++++++++++------------------------------
 1 file changed, 20 insertions(+), 30 deletions(-)

-- 
2.41.0.162.gfafddb0af9-goog



^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCHv2 1/3] zsmalloc: do not scan for allocated objects in empty zspage
  2023-06-24  5:12 [PATCHv2 0/3] zsmalloc: small compaction improvements Sergey Senozhatsky
@ 2023-06-24  5:12 ` Sergey Senozhatsky
  2023-06-26 10:57   ` Alexey Romanov
  2023-06-26 17:13   ` Minchan Kim
  2023-06-24  5:12 ` [PATCHv2 2/3] zsmalloc: move migration destination zspage inuse check Sergey Senozhatsky
                   ` (2 subsequent siblings)
  3 siblings, 2 replies; 12+ messages in thread
From: Sergey Senozhatsky @ 2023-06-24  5:12 UTC (permalink / raw)
  To: Andrew Morton, Minchan Kim
  Cc: linux-mm, linux-kernel, Sergey Senozhatsky, Alexey Romanov

zspage migration can terminate as soon as it moves the last
allocated object from the source zspage.  Add a simple helper
zspage_empty() that tests zspage ->inuse on each migration
iteration.

Suggested-by: Alexey Romanov <AVRomanov@sberdevices.ru>
Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
---
 mm/zsmalloc.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c
index 3f057970504e..5d60eaedc3b7 100644
--- a/mm/zsmalloc.c
+++ b/mm/zsmalloc.c
@@ -1147,6 +1147,11 @@ static bool zspage_full(struct size_class *class, struct zspage *zspage)
 	return get_zspage_inuse(zspage) == class->objs_per_zspage;
 }
 
+static bool zspage_empty(struct zspage *zspage)
+{
+	return get_zspage_inuse(zspage) == 0;
+}
+
 /**
  * zs_lookup_class_index() - Returns index of the zsmalloc &size_class
  * that hold objects of the provided size.
@@ -1625,6 +1630,10 @@ static void migrate_zspage(struct zs_pool *pool, struct size_class *class,
 		obj_idx++;
 		record_obj(handle, free_obj);
 		obj_free(class->size, used_obj);
+
+		/* Stop if there are no more objects to migrate */
+		if (zspage_empty(get_zspage(s_page)))
+			break;
 	}
 
 	/* Remember last position in this iteration */
-- 
2.41.0.162.gfafddb0af9-goog



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCHv2 2/3] zsmalloc: move migration destination zspage inuse check
  2023-06-24  5:12 [PATCHv2 0/3] zsmalloc: small compaction improvements Sergey Senozhatsky
  2023-06-24  5:12 ` [PATCHv2 1/3] zsmalloc: do not scan for allocated objects in empty zspage Sergey Senozhatsky
@ 2023-06-24  5:12 ` Sergey Senozhatsky
  2023-06-26 17:13   ` Minchan Kim
  2023-06-24  5:12 ` [PATCHv2 3/3] zsmalloc: remove zs_compact_control Sergey Senozhatsky
  2023-07-05 13:28 ` [PATCHv2 0/3] zsmalloc: small compaction improvements Sergey Senozhatsky
  3 siblings, 1 reply; 12+ messages in thread
From: Sergey Senozhatsky @ 2023-06-24  5:12 UTC (permalink / raw)
  To: Andrew Morton, Minchan Kim; +Cc: linux-mm, linux-kernel, Sergey Senozhatsky

Destination zspage fullness check need to be done after
zs_object_copy() because that's where source and destination
zspages fullness change.  Checking destination zspage fullness
before zs_object_copy() may cause migration to loop through
source zspage sub-pages scanning for allocate objects just to
find out at the end that the destination zspage is full.

Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
---
 mm/zsmalloc.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c
index 5d60eaedc3b7..4a84f7877669 100644
--- a/mm/zsmalloc.c
+++ b/mm/zsmalloc.c
@@ -1620,10 +1620,6 @@ static void migrate_zspage(struct zs_pool *pool, struct size_class *class,
 			continue;
 		}
 
-		/* Stop if there is no more space */
-		if (zspage_full(class, get_zspage(d_page)))
-			break;
-
 		used_obj = handle_to_obj(handle);
 		free_obj = obj_malloc(pool, get_zspage(d_page), handle);
 		zs_object_copy(class, free_obj, used_obj);
@@ -1631,6 +1627,10 @@ static void migrate_zspage(struct zs_pool *pool, struct size_class *class,
 		record_obj(handle, free_obj);
 		obj_free(class->size, used_obj);
 
+		/* Stop if there is no more space */
+		if (zspage_full(class, get_zspage(d_page)))
+			break;
+
 		/* Stop if there are no more objects to migrate */
 		if (zspage_empty(get_zspage(s_page)))
 			break;
-- 
2.41.0.162.gfafddb0af9-goog



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCHv2 3/3] zsmalloc: remove zs_compact_control
  2023-06-24  5:12 [PATCHv2 0/3] zsmalloc: small compaction improvements Sergey Senozhatsky
  2023-06-24  5:12 ` [PATCHv2 1/3] zsmalloc: do not scan for allocated objects in empty zspage Sergey Senozhatsky
  2023-06-24  5:12 ` [PATCHv2 2/3] zsmalloc: move migration destination zspage inuse check Sergey Senozhatsky
@ 2023-06-24  5:12 ` Sergey Senozhatsky
  2023-06-25  6:10   ` Sergey Senozhatsky
  2023-06-26 17:14   ` Minchan Kim
  2023-07-05 13:28 ` [PATCHv2 0/3] zsmalloc: small compaction improvements Sergey Senozhatsky
  3 siblings, 2 replies; 12+ messages in thread
From: Sergey Senozhatsky @ 2023-06-24  5:12 UTC (permalink / raw)
  To: Andrew Morton, Minchan Kim; +Cc: linux-mm, linux-kernel

From: Minchan Kim <minchan@kernel.org>

__zs_compact always putback src_zspage into class list after
migrate_zspage. Thus, we don't need to keep last position of
src_zspage any more. Let's remove it.

Signed-off-by: Minchan Kim <minchan@kernel.org>
---
 mm/zsmalloc.c | 37 +++++++++----------------------------
 1 file changed, 9 insertions(+), 28 deletions(-)

diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c
index 4a84f7877669..84beadc088b8 100644
--- a/mm/zsmalloc.c
+++ b/mm/zsmalloc.c
@@ -1590,25 +1590,14 @@ static unsigned long find_alloced_obj(struct size_class *class,
 	return find_tagged_obj(class, page, obj_idx, OBJ_ALLOCATED_TAG);
 }
 
-struct zs_compact_control {
-	/* Source spage for migration which could be a subpage of zspage */
-	struct page *s_page;
-	/* Destination page for migration which should be a first page
-	 * of zspage. */
-	struct page *d_page;
-	 /* Starting object index within @s_page which used for live object
-	  * in the subpage. */
-	int obj_idx;
-};
-
-static void migrate_zspage(struct zs_pool *pool, struct size_class *class,
-			   struct zs_compact_control *cc)
+static void migrate_zspage(struct zs_pool *pool, struct zspage *src_zspage,
+			   struct zspage *dst_zspage)
 {
 	unsigned long used_obj, free_obj;
 	unsigned long handle;
-	struct page *s_page = cc->s_page;
-	struct page *d_page = cc->d_page;
-	int obj_idx = cc->obj_idx;
+	int obj_idx = 0;
+	struct page *s_page = get_first_page(src_zspage);
+	struct size_class *class = pool->size_class[src_zspage->class];
 
 	while (1) {
 		handle = find_alloced_obj(class, s_page, &obj_idx);
@@ -1621,24 +1610,20 @@ static void migrate_zspage(struct zs_pool *pool, struct size_class *class,
 		}
 
 		used_obj = handle_to_obj(handle);
-		free_obj = obj_malloc(pool, get_zspage(d_page), handle);
+		free_obj = obj_malloc(pool, dst_zspage, handle);
 		zs_object_copy(class, free_obj, used_obj);
 		obj_idx++;
 		record_obj(handle, free_obj);
 		obj_free(class->size, used_obj);
 
 		/* Stop if there is no more space */
-		if (zspage_full(class, get_zspage(d_page)))
+		if (zspage_full(class, dst_zspage))
 			break;
 
 		/* Stop if there are no more objects to migrate */
-		if (zspage_empty(get_zspage(s_page)))
+		if (zspage_empty(src_zspage))
 			break;
 	}
-
-	/* Remember last position in this iteration */
-	cc->s_page = s_page;
-	cc->obj_idx = obj_idx;
 }
 
 static struct zspage *isolate_src_zspage(struct size_class *class)
@@ -2013,7 +1998,6 @@ static unsigned long zs_can_compact(struct size_class *class)
 static unsigned long __zs_compact(struct zs_pool *pool,
 				  struct size_class *class)
 {
-	struct zs_compact_control cc;
 	struct zspage *src_zspage = NULL;
 	struct zspage *dst_zspage = NULL;
 	unsigned long pages_freed = 0;
@@ -2031,7 +2015,6 @@ static unsigned long __zs_compact(struct zs_pool *pool,
 			if (!dst_zspage)
 				break;
 			migrate_write_lock(dst_zspage);
-			cc.d_page = get_first_page(dst_zspage);
 		}
 
 		src_zspage = isolate_src_zspage(class);
@@ -2040,9 +2023,7 @@ static unsigned long __zs_compact(struct zs_pool *pool,
 
 		migrate_write_lock_nested(src_zspage);
 
-		cc.obj_idx = 0;
-		cc.s_page = get_first_page(src_zspage);
-		migrate_zspage(pool, class, &cc);
+		migrate_zspage(pool, src_zspage, dst_zspage);
 		fg = putback_zspage(class, src_zspage);
 		migrate_write_unlock(src_zspage);
 
-- 
2.41.0.162.gfafddb0af9-goog



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCHv2 3/3] zsmalloc: remove zs_compact_control
  2023-06-24  5:12 ` [PATCHv2 3/3] zsmalloc: remove zs_compact_control Sergey Senozhatsky
@ 2023-06-25  6:10   ` Sergey Senozhatsky
  2023-06-26 17:14   ` Minchan Kim
  1 sibling, 0 replies; 12+ messages in thread
From: Sergey Senozhatsky @ 2023-06-25  6:10 UTC (permalink / raw)
  To: Sergey Senozhatsky; +Cc: Andrew Morton, Minchan Kim, linux-mm, linux-kernel

On (23/06/24 14:12), Sergey Senozhatsky wrote:
> __zs_compact always putback src_zspage into class list after
> migrate_zspage. Thus, we don't need to keep last position of
> src_zspage any more. Let's remove it.
> 
> Signed-off-by: Minchan Kim <minchan@kernel.org>

Acked-by: Sergey Senozhatsky <senozhatsky@chromium.org>


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCHv2 1/3] zsmalloc: do not scan for allocated objects in empty zspage
  2023-06-24  5:12 ` [PATCHv2 1/3] zsmalloc: do not scan for allocated objects in empty zspage Sergey Senozhatsky
@ 2023-06-26 10:57   ` Alexey Romanov
  2023-07-01 10:39     ` Sergey Senozhatsky
  2023-06-26 17:13   ` Minchan Kim
  1 sibling, 1 reply; 12+ messages in thread
From: Alexey Romanov @ 2023-06-26 10:57 UTC (permalink / raw)
  To: Sergey Senozhatsky
  Cc: Andrew Morton, Minchan Kim, linux-mm@kvack.org,
	linux-kernel@vger.kernel.org

Hi,

On Sat, Jun 24, 2023 at 02:12:14PM +0900, Sergey Senozhatsky wrote:
> zspage migration can terminate as soon as it moves the last
> allocated object from the source zspage.  Add a simple helper
> zspage_empty() that tests zspage ->inuse on each migration
> iteration.
> 
> Suggested-by: Alexey Romanov <AVRomanov@sberdevices.ru>
> Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
> ---
>  mm/zsmalloc.c | 9 +++++++++
>  1 file changed, 9 insertions(+)
> 
> diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c
> index 3f057970504e..5d60eaedc3b7 100644
> --- a/mm/zsmalloc.c
> +++ b/mm/zsmalloc.c
> @@ -1147,6 +1147,11 @@ static bool zspage_full(struct size_class *class, struct zspage *zspage)
>  	return get_zspage_inuse(zspage) == class->objs_per_zspage;
>  }
>  
> +static bool zspage_empty(struct zspage *zspage)
> +{
> +	return get_zspage_inuse(zspage) == 0;
> +}
> +
>  /**
>   * zs_lookup_class_index() - Returns index of the zsmalloc &size_class
>   * that hold objects of the provided size.
> @@ -1625,6 +1630,10 @@ static void migrate_zspage(struct zs_pool *pool, struct size_class *class,
>  		obj_idx++;
>  		record_obj(handle, free_obj);
>  		obj_free(class->size, used_obj);
> +
> +		/* Stop if there are no more objects to migrate */
> +		if (zspage_empty(get_zspage(s_page)))
> +			break;
>  	}
>  
>  	/* Remember last position in this iteration */
> -- 
> 2.41.0.162.gfafddb0af9-goog
> 

not sure if I can keep this tag but,

Reviewed-by: Alexey Romanov <avromanov@sberdevices.ru>

-- 
Thank you,
Alexey

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCHv2 1/3] zsmalloc: do not scan for allocated objects in empty zspage
  2023-06-24  5:12 ` [PATCHv2 1/3] zsmalloc: do not scan for allocated objects in empty zspage Sergey Senozhatsky
  2023-06-26 10:57   ` Alexey Romanov
@ 2023-06-26 17:13   ` Minchan Kim
  1 sibling, 0 replies; 12+ messages in thread
From: Minchan Kim @ 2023-06-26 17:13 UTC (permalink / raw)
  To: Sergey Senozhatsky; +Cc: Andrew Morton, linux-mm, linux-kernel, Alexey Romanov

On Sat, Jun 24, 2023 at 02:12:14PM +0900, Sergey Senozhatsky wrote:
> zspage migration can terminate as soon as it moves the last
> allocated object from the source zspage.  Add a simple helper
> zspage_empty() that tests zspage ->inuse on each migration
> iteration.
> 
> Suggested-by: Alexey Romanov <AVRomanov@sberdevices.ru>
> Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
Acked-by: Minchan Kim <minchan@kernel.org>


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCHv2 2/3] zsmalloc: move migration destination zspage inuse check
  2023-06-24  5:12 ` [PATCHv2 2/3] zsmalloc: move migration destination zspage inuse check Sergey Senozhatsky
@ 2023-06-26 17:13   ` Minchan Kim
  0 siblings, 0 replies; 12+ messages in thread
From: Minchan Kim @ 2023-06-26 17:13 UTC (permalink / raw)
  To: Sergey Senozhatsky; +Cc: Andrew Morton, linux-mm, linux-kernel

On Sat, Jun 24, 2023 at 02:12:15PM +0900, Sergey Senozhatsky wrote:
> Destination zspage fullness check need to be done after
> zs_object_copy() because that's where source and destination
> zspages fullness change.  Checking destination zspage fullness
> before zs_object_copy() may cause migration to loop through
> source zspage sub-pages scanning for allocate objects just to
> find out at the end that the destination zspage is full.
> 
> Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
Acked-by: Minchan Kim <minchan@kernel.org> 


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCHv2 3/3] zsmalloc: remove zs_compact_control
  2023-06-24  5:12 ` [PATCHv2 3/3] zsmalloc: remove zs_compact_control Sergey Senozhatsky
  2023-06-25  6:10   ` Sergey Senozhatsky
@ 2023-06-26 17:14   ` Minchan Kim
  2023-07-01 11:06     ` Sergey Senozhatsky
  1 sibling, 1 reply; 12+ messages in thread
From: Minchan Kim @ 2023-06-26 17:14 UTC (permalink / raw)
  To: Sergey Senozhatsky; +Cc: Andrew Morton, linux-mm, linux-kernel

On Sat, Jun 24, 2023 at 02:12:16PM +0900, Sergey Senozhatsky wrote:
> From: Minchan Kim <minchan@kernel.org>
> 
> __zs_compact always putback src_zspage into class list after
> migrate_zspage. Thus, we don't need to keep last position of
> src_zspage any more. Let's remove it.
> 
> Signed-off-by: Minchan Kim <minchan@kernel.org>
 
 Thanks for picking it up, Sergey!


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCHv2 1/3] zsmalloc: do not scan for allocated objects in empty zspage
  2023-06-26 10:57   ` Alexey Romanov
@ 2023-07-01 10:39     ` Sergey Senozhatsky
  0 siblings, 0 replies; 12+ messages in thread
From: Sergey Senozhatsky @ 2023-07-01 10:39 UTC (permalink / raw)
  To: Alexey Romanov
  Cc: Sergey Senozhatsky, Andrew Morton, Minchan Kim,
	linux-mm@kvack.org, linux-kernel@vger.kernel.org

On (23/06/26 10:57), Alexey Romanov wrote:
> not sure if I can keep this tag but,

Sure, why not

> 
> Reviewed-by: Alexey Romanov <avromanov@sberdevices.ru>


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCHv2 3/3] zsmalloc: remove zs_compact_control
  2023-06-26 17:14   ` Minchan Kim
@ 2023-07-01 11:06     ` Sergey Senozhatsky
  0 siblings, 0 replies; 12+ messages in thread
From: Sergey Senozhatsky @ 2023-07-01 11:06 UTC (permalink / raw)
  To: Minchan Kim; +Cc: Sergey Senozhatsky, Andrew Morton, linux-mm, linux-kernel

On (23/06/26 10:14), Minchan Kim wrote:
> On Sat, Jun 24, 2023 at 02:12:16PM +0900, Sergey Senozhatsky wrote:
> > From: Minchan Kim <minchan@kernel.org>
> > 
> > __zs_compact always putback src_zspage into class list after
> > migrate_zspage. Thus, we don't need to keep last position of
> > src_zspage any more. Let's remove it.
> > 
> > Signed-off-by: Minchan Kim <minchan@kernel.org>
>  
>  Thanks for picking it up, Sergey!

Thank you for clearing up the code!


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCHv2 0/3] zsmalloc: small compaction improvements
  2023-06-24  5:12 [PATCHv2 0/3] zsmalloc: small compaction improvements Sergey Senozhatsky
                   ` (2 preceding siblings ...)
  2023-06-24  5:12 ` [PATCHv2 3/3] zsmalloc: remove zs_compact_control Sergey Senozhatsky
@ 2023-07-05 13:28 ` Sergey Senozhatsky
  3 siblings, 0 replies; 12+ messages in thread
From: Sergey Senozhatsky @ 2023-07-05 13:28 UTC (permalink / raw)
  To: Andrew Morton, Minchan Kim; +Cc: linux-mm, linux-kernel, Sergey Senozhatsky

On (23/06/24 14:12), Sergey Senozhatsky wrote:
> Hi,
> 	A tiny series that can reduce the number of
> find_alloced_obj() invocations (which perform a linear
> scan of sub-page) during compaction. Inspired by Alexey
> Romanov's findings.
> 
> v2:
> -- picked up a patch from Minchan
> 
> Minchan Kim (1):
>   zsmalloc: remove zs_compact_control
> 
> Sergey Senozhatsky (2):
>   zsmalloc: do not scan for allocated objects in empty zspage
>   zsmalloc: move migration destination zspage inuse check

Just for the record,

A synthetic zsmalloc fragmentation+compaction test (100% reproducible)

           num find_tagged_obj() calls     num iterations in find_tagged_obj()

base                 545699                              812899
patch #1             460701                              691821
patch #2             422372                              651372

// lower is better


patch #1 is "zsmalloc: do not scan for allocated objects in empty zspage"
patch #2 is "zsmalloc: move migration destination zspage inuse check"


^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2023-07-05 13:29 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-06-24  5:12 [PATCHv2 0/3] zsmalloc: small compaction improvements Sergey Senozhatsky
2023-06-24  5:12 ` [PATCHv2 1/3] zsmalloc: do not scan for allocated objects in empty zspage Sergey Senozhatsky
2023-06-26 10:57   ` Alexey Romanov
2023-07-01 10:39     ` Sergey Senozhatsky
2023-06-26 17:13   ` Minchan Kim
2023-06-24  5:12 ` [PATCHv2 2/3] zsmalloc: move migration destination zspage inuse check Sergey Senozhatsky
2023-06-26 17:13   ` Minchan Kim
2023-06-24  5:12 ` [PATCHv2 3/3] zsmalloc: remove zs_compact_control Sergey Senozhatsky
2023-06-25  6:10   ` Sergey Senozhatsky
2023-06-26 17:14   ` Minchan Kim
2023-07-01 11:06     ` Sergey Senozhatsky
2023-07-05 13:28 ` [PATCHv2 0/3] zsmalloc: small compaction improvements Sergey Senozhatsky

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.