Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1338850 > unrolled thread
| Started by | Sergey Senozhatsky <sergey.senozhatsky@gmail.com> |
|---|---|
| First post | 2016-02-21 18:30 +0100 |
| Last post | 2016-02-22 03:30 +0100 |
| Articles | 20 on this page of 22 — 3 participants |
Back to article view | Back to linux.kernel
[RFC][PATCH v2 0/3] mm/zsmalloc: increase objects density and reduce memory wastage Sergey Senozhatsky <sergey.senozhatsky@gmail.com> - 2016-02-21 18:30 +0100
[RFC][PATCH v2 2/3] zram: use zs_get_huge_class_size_watermark() Sergey Senozhatsky <sergey.senozhatsky@gmail.com> - 2016-02-21 18:50 +0100
Re: [RFC][PATCH v2 2/3] zram: use zs_get_huge_class_size_watermark() Minchan Kim <minchan@kernel.org> - 2016-02-22 01:10 +0100
Re: [RFC][PATCH v2 2/3] zram: use zs_get_huge_class_size_watermark() Sergey Senozhatsky <sergey.senozhatsky.work@gmail.com> - 2016-02-22 01:40 +0100
Re: [RFC][PATCH v2 2/3] zram: use zs_get_huge_class_size_watermark() Minchan Kim <minchan@kernel.org> - 2016-02-22 02:30 +0100
Re: [RFC][PATCH v2 2/3] zram: use zs_get_huge_class_size_watermark() Sergey Senozhatsky <sergey.senozhatsky.work@gmail.com> - 2016-02-22 03:00 +0100
Re: [RFC][PATCH v2 2/3] zram: use zs_get_huge_class_size_watermark() Sergey Senozhatsky <sergey.senozhatsky.work@gmail.com> - 2016-02-22 03:10 +0100
Re: [RFC][PATCH v2 2/3] zram: use zs_get_huge_class_size_watermark() Minchan Kim <minchan@kernel.org> - 2016-02-22 04:00 +0100
Re: [RFC][PATCH v2 2/3] zram: use zs_get_huge_class_size_watermark() Sergey Senozhatsky <sergey.senozhatsky.work@gmail.com> - 2016-02-22 05:00 +0100
Re: [RFC][PATCH v2 2/3] zram: use zs_get_huge_class_size_watermark() Minchan Kim <minchan@kernel.org> - 2016-02-22 06:00 +0100
Re: [RFC][PATCH v2 2/3] zram: use zs_get_huge_class_size_watermark() Sergey Senozhatsky <sergey.senozhatsky.work@gmail.com> - 2016-02-22 06:10 +0100
[RFC][PATCH v2 1/3] mm/zsmalloc: introduce zs_get_huge_class_size_watermark() Sergey Senozhatsky <sergey.senozhatsky@gmail.com> - 2016-02-21 19:50 +0100
[RFC][PATCH v2 3/3] mm/zsmalloc: increase ZS_MAX_PAGES_PER_ZSPAGE Sergey Senozhatsky <sergey.senozhatsky@gmail.com> - 2016-02-21 20:00 +0100
Re: [RFC][PATCH v2 3/3] mm/zsmalloc: increase ZS_MAX_PAGES_PER_ZSPAGE Minchan Kim <minchan@kernel.org> - 2016-02-22 01:30 +0100
Re: [RFC][PATCH v2 3/3] mm/zsmalloc: increase ZS_MAX_PAGES_PER_ZSPAGE Sergey Senozhatsky <sergey.senozhatsky.work@gmail.com> - 2016-02-22 01:50 +0100
Re: [RFC][PATCH v2 3/3] mm/zsmalloc: increase ZS_MAX_PAGES_PER_ZSPAGE Minchan Kim <minchan@kernel.org> - 2016-02-22 02:40 +0100
Re: [RFC][PATCH v2 3/3] mm/zsmalloc: increase ZS_MAX_PAGES_PER_ZSPAGE Sergey Senozhatsky <sergey.senozhatsky.work@gmail.com> - 2016-02-22 03:10 +0100
Re: [RFC][PATCH v2 3/3] mm/zsmalloc: increase ZS_MAX_PAGES_PER_ZSPAGE Minchan Kim <minchan@kernel.org> - 2016-02-22 03:40 +0100
Re: [RFC][PATCH v2 3/3] mm/zsmalloc: increase ZS_MAX_PAGES_PER_ZSPAGE Sergey Senozhatsky <sergey.senozhatsky.work@gmail.com> - 2016-02-22 05:00 +0100
Re: [RFC][PATCH v2 3/3] mm/zsmalloc: increase ZS_MAX_PAGES_PER_ZSPAGE Minchan Kim <minchan@kernel.org> - 2016-02-22 05:50 +0100
Re: [RFC][PATCH v2 3/3] mm/zsmalloc: increase ZS_MAX_PAGES_PER_ZSPAGE Sergey Senozhatsky <sergey.senozhatsky.work@gmail.com> - 2016-02-22 11:50 +0100
Re: [RFC][PATCH v2 3/3] mm/zsmalloc: increase ZS_MAX_PAGES_PER_ZSPAGE Sergey Senozhatsky <sergey.senozhatsky.work@gmail.com> - 2016-02-22 03:30 +0100
Page 1 of 2 [1] 2 Next page →
| From | Sergey Senozhatsky <sergey.senozhatsky@gmail.com> |
|---|---|
| Date | 2016-02-21 18:30 +0100 |
| Subject | [RFC][PATCH v2 0/3] mm/zsmalloc: increase objects density and reduce memory wastage |
| Message-ID | <r4FZw-Tg-3@gated-at.bofh.it> |
Hello, RFC huge classes are evil. zsmalloc knows the watermark after which classes are considered to be ->huge - every object stored consumes the entire zspage (which consist of a single order-0 page). zram, however, has its own statically defined watermark for `bad' compression and stores every object larger than this watermark as a PAGE_SIZE, object, IOW, to a ->huge class, this results in increased memory consumption and memory wastage. And zram's 'bad' watermark is much lower than zsmalloc's one. Apart from that, 'bad' compressions are not so rare, on some of my tests 41% of writes are 'bad' compressions. This patch set inverts this 'huge class watermark' enforcement, it's zsmalloc that knows better, not zram. It also reduces the number of huge classes, this saves some memory. Since we request less pages for object larger than 3072 bytes, zmalloc in some cases should behave nicer when the system is getting low on free pages. Object's location is encoded as <PFN, OBJ_INDEX_BITS | OBJ_ALLOCATED_TAG | HANDLE_PIN_BIT> so mostly we have enough bits in OBJ_INDEX_BITS to increase ZS_MAX_ZSPAGE_ORDER and keep all of the classes. This is not true, however, on PAE/LPAE and PAGE_SHIFT 16 systems, so we need to preserve the exiting ZS_MAX_ZSPAGE_ORDER 2 limit there. Please commit 0003 for some numbers. Thanks to Joonsoo Kim for valuable questions and opinions. v2: -- keep ZS_MAX_PAGES_PER_ZSPAGE order of two (Joonsoo) -- suffice ZS_MIN_ALLOC_SIZE alignment requirement -- do not change ZS_MAX_PAGES_PER_ZSPAGE on PAE/LPAE and on PAGE_SHIFT 16 systems (Joonsoo) Sergey Senozhatsky (3): mm/zsmalloc: introduce zs_get_huge_class_size_watermark() zram: use zs_get_huge_class_size_watermark() mm/zsmalloc: increase ZS_MAX_PAGES_PER_ZSPAGE drivers/block/zram/zram_drv.c | 2 +- drivers/block/zram/zram_drv.h | 6 ------ include/linux/zsmalloc.h | 2 ++ mm/zsmalloc.c | 43 ++++++++++++++++++++++++++++++++++++------- 4 files changed, 39 insertions(+), 14 deletions(-) -- 2.7.1
[toc] | [next] | [standalone]
| From | Sergey Senozhatsky <sergey.senozhatsky@gmail.com> |
|---|---|
| Date | 2016-02-21 18:50 +0100 |
| Subject | [RFC][PATCH v2 2/3] zram: use zs_get_huge_class_size_watermark() |
| Message-ID | <r4GiT-12G-33@gated-at.bofh.it> |
| In reply to | #1338850 |
From: Sergey Senozhatsky <sergey.senozhatsky.work@gmail.com>
zram should stop enforcing its own 'bad' object size watermark,
and start using zs_get_huge_class_size_watermark(). zsmalloc
really knows better.
Drop `max_zpage_size' and use zs_get_huge_class_size_watermark()
instead.
Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
---
drivers/block/zram/zram_drv.c | 2 +-
drivers/block/zram/zram_drv.h | 6 ------
2 files changed, 1 insertion(+), 7 deletions(-)
diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
index 46055db..2621564 100644
--- a/drivers/block/zram/zram_drv.c
+++ b/drivers/block/zram/zram_drv.c
@@ -714,7 +714,7 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index,
goto out;
}
src = zstrm->buffer;
- if (unlikely(clen > max_zpage_size)) {
+ if (unlikely(clen > zs_get_huge_class_size_watermark())) {
clen = PAGE_SIZE;
if (is_partial_io(bvec))
src = uncmem;
diff --git a/drivers/block/zram/zram_drv.h b/drivers/block/zram/zram_drv.h
index 8e92339..8879161 100644
--- a/drivers/block/zram/zram_drv.h
+++ b/drivers/block/zram/zram_drv.h
@@ -23,12 +23,6 @@
/*-- Configurable parameters */
/*
- * Pages that compress to size greater than this are stored
- * uncompressed in memory.
- */
-static const size_t max_zpage_size = PAGE_SIZE / 4 * 3;
-
-/*
* NOTE: max_zpage_size must be less than or equal to:
* ZS_MAX_ALLOC_SIZE. Otherwise, zs_malloc() would
* always return failure.
--
2.7.1
[toc] | [prev] | [next] | [standalone]
| From | Minchan Kim <minchan@kernel.org> |
|---|---|
| Date | 2016-02-22 01:10 +0100 |
| Subject | Re: [RFC][PATCH v2 2/3] zram: use zs_get_huge_class_size_watermark() |
| Message-ID | <r4MeC-5Gm-7@gated-at.bofh.it> |
| In reply to | #1338882 |
On Sun, Feb 21, 2016 at 10:27:53PM +0900, Sergey Senozhatsky wrote:
> From: Sergey Senozhatsky <sergey.senozhatsky.work@gmail.com>
>
> zram should stop enforcing its own 'bad' object size watermark,
> and start using zs_get_huge_class_size_watermark(). zsmalloc
> really knows better.
>
> Drop `max_zpage_size' and use zs_get_huge_class_size_watermark()
> instead.
max_zpage_size was there since zram's grandpa(ie, ramzswap).
AFAIR, at that time, it works to forward incompressible
(e.g, PAGE_SIZE/2) page to backing swap if it presents.
If it doesn't have any backing swap and it's incompressbile
(e.g, PAGE_SIZE*3/4), it stores it as uncompressed page
to avoid *decompress* overhead later. And Nitin want to make
it as tunable parameter. I agree the approach because I don't
want to make coupling between zram and allocator as far as
possible.
If huge class is pain, it's allocator problem, not zram stuff.
I think we should try to remove such problem in zsmalloc layer,
firstly.
Having said that, I agree your claim that uncompressible pages
are pain. I want to handle the problem as multiple-swap apparoach.
Now, zram is very popular and I expect we will use multiple
swap(i.e., zram swap + eMMC swap) shortly. For that case, we could
forward uncompressible page to the eMMC swap with simple tweaking
of swap subsystem if zram returns error once it found it's
incompressible page.
For that, we should introduce new knob in zram layer like Nitin
did and make it configurable so we could solve the problem of
single zram-swap system as well as multiple swap system.
>
> Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
> ---
> drivers/block/zram/zram_drv.c | 2 +-
> drivers/block/zram/zram_drv.h | 6 ------
> 2 files changed, 1 insertion(+), 7 deletions(-)
>
> diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
> index 46055db..2621564 100644
> --- a/drivers/block/zram/zram_drv.c
> +++ b/drivers/block/zram/zram_drv.c
> @@ -714,7 +714,7 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index,
> goto out;
> }
> src = zstrm->buffer;
> - if (unlikely(clen > max_zpage_size)) {
> + if (unlikely(clen > zs_get_huge_class_size_watermark())) {
> clen = PAGE_SIZE;
> if (is_partial_io(bvec))
> src = uncmem;
> diff --git a/drivers/block/zram/zram_drv.h b/drivers/block/zram/zram_drv.h
> index 8e92339..8879161 100644
> --- a/drivers/block/zram/zram_drv.h
> +++ b/drivers/block/zram/zram_drv.h
> @@ -23,12 +23,6 @@
> /*-- Configurable parameters */
>
> /*
> - * Pages that compress to size greater than this are stored
> - * uncompressed in memory.
> - */
> -static const size_t max_zpage_size = PAGE_SIZE / 4 * 3;
> -
> -/*
> * NOTE: max_zpage_size must be less than or equal to:
> * ZS_MAX_ALLOC_SIZE. Otherwise, zs_malloc() would
> * always return failure.
> --
> 2.7.1
>
[toc] | [prev] | [next] | [standalone]
| From | Sergey Senozhatsky <sergey.senozhatsky.work@gmail.com> |
|---|---|
| Date | 2016-02-22 01:40 +0100 |
| Subject | Re: [RFC][PATCH v2 2/3] zram: use zs_get_huge_class_size_watermark() |
| Message-ID | <r4MHF-5TA-31@gated-at.bofh.it> |
| In reply to | #1339018 |
On (02/22/16 09:04), Minchan Kim wrote: [..] > max_zpage_size was there since zram's grandpa(ie, ramzswap). > AFAIR, at that time, it works to forward incompressible > (e.g, PAGE_SIZE/2) page to backing swap if it presents. > If it doesn't have any backing swap and it's incompressbile > (e.g, PAGE_SIZE*3/4), it stores it as uncompressed page > to avoid *decompress* overhead later. "PAGE_SIZE * 3 / 4" introduces a bigger memory overhead than decompression of 3K bytes later. > And Nitin want to make it as tunable parameter. I agree the > approach because I don't want to make coupling between zram > and allocator as far as possible. > > If huge class is pain they are. > it's allocator problem, not zram stuff. the allocator's problems start at the point where zram begins to have opinion on what should be stored as ->huge object and what should not. it's not up to zram to enforce this. > I think we should try to remove such problem in zsmalloc layer, > firstly. zram asks to store a PAGE_SIZE sized object, what zsmalloc can possible do about this? > Having said that, I agree your claim that uncompressible pages > are pain. I want to handle the problem as multiple-swap apparoach. zram is not just for swapping. as simple as that. and enforcing a multi-swap approach on folks who use zram for swap doesn't look right to me. > For that, we should introduce new knob in zram layer like Nitin > did and make it configurable so we could solve the problem of > single zram-swap system as well as multiple swap system. a 'bad compression' watermark knob? isn't it an absolutely low level thing no one ever should see? -ss
[toc] | [prev] | [next] | [standalone]
| From | Minchan Kim <minchan@kernel.org> |
|---|---|
| Date | 2016-02-22 02:30 +0100 |
| Subject | Re: [RFC][PATCH v2 2/3] zram: use zs_get_huge_class_size_watermark() |
| Message-ID | <r4Nu1-6vc-1@gated-at.bofh.it> |
| In reply to | #1339036 |
On Mon, Feb 22, 2016 at 09:40:47AM +0900, Sergey Senozhatsky wrote:
> On (02/22/16 09:04), Minchan Kim wrote:
> [..]
> > max_zpage_size was there since zram's grandpa(ie, ramzswap).
> > AFAIR, at that time, it works to forward incompressible
> > (e.g, PAGE_SIZE/2) page to backing swap if it presents.
> > If it doesn't have any backing swap and it's incompressbile
> > (e.g, PAGE_SIZE*3/4), it stores it as uncompressed page
> > to avoid *decompress* overhead later.
>
> "PAGE_SIZE * 3 / 4" introduces a bigger memory overhead than
> decompression of 3K bytes later.
>
> > And Nitin want to make it as tunable parameter. I agree the
> > approach because I don't want to make coupling between zram
> > and allocator as far as possible.
> >
> > If huge class is pain
>
> they are.
>
> > it's allocator problem, not zram stuff.
>
> the allocator's problems start at the point where zram begins to have
> opinion on what should be stored as ->huge object and what should not.
> it's not up to zram to enforce this.
>
>
> > I think we should try to remove such problem in zsmalloc layer,
> > firstly.
>
> zram asks to store a PAGE_SIZE sized object, what zsmalloc can
> possible do about this?
zsmalloc can increase ZS_MAX_ZSPAGE_ORDER or can save metadata in
the extra space. In fact, I tried interlink approach long time ago.
For example, class-A -> class-B
A = x, B = (4096 - y) >= x
The problem was class->B zspage consumes memory although there is
no object in the zspage because class-A object in the extra space
of class-B pin the class-B zspage.
I prefer your ZS_MAX_ZSPAGE_ORDER increaing approach but as I told
in that thread, we should prepare dynamic creating of sub-page
in zspage.
>
>
> > Having said that, I agree your claim that uncompressible pages
> > are pain. I want to handle the problem as multiple-swap apparoach.
>
> zram is not just for swapping. as simple as that.
Yes, I mean if we have backing storage, we could mitigate the problem
like the mentioned approach. Otherwise, we should solve it in allocator
itself and you suggested the idea and I commented first step.
What's the problem, now?
>
>
> and enforcing a multi-swap approach on folks who use zram for swap
> doesn't look right to me.
Ditto.
>
>
> > For that, we should introduce new knob in zram layer like Nitin
> > did and make it configurable so we could solve the problem of
> > single zram-swap system as well as multiple swap system.
>
> a 'bad compression' watermark knob? isn't it an absolutely low level
> thing no one ever should see?
It's a knob to determine that how to handle incompressible page
in zram layer. For example, admin can tune it to 2048. It means
if we have backing store and compressed ratio is under 50%,
admin want to pass the page into swap storage. If the system
is no backed store, it means admin want to avoid decompress
overhead if the ratio is smaller.
I don't think it's a low level thing.
>
> -ss
[toc] | [prev] | [next] | [standalone]
| From | Sergey Senozhatsky <sergey.senozhatsky.work@gmail.com> |
|---|---|
| Date | 2016-02-22 03:00 +0100 |
| Subject | Re: [RFC][PATCH v2 2/3] zram: use zs_get_huge_class_size_watermark() |
| Message-ID | <r4NX4-6FN-9@gated-at.bofh.it> |
| In reply to | #1339046 |
On (02/22/16 10:27), Minchan Kim wrote: [..] > > zram asks to store a PAGE_SIZE sized object, what zsmalloc can > > possible do about this? > > zsmalloc can increase ZS_MAX_ZSPAGE_ORDER or can save metadata in > the extra space. In fact, I tried interlink approach long time ago. > For example, class-A -> class-B > > A = x, B = (4096 - y) >= x > > The problem was class->B zspage consumes memory although there is > no object in the zspage because class-A object in the extra space > of class-B pin the class-B zspage. I thought about it too -- utilizing 'unused space' to store there smaller objects. and I think it potentially has more problems. compaction (and everything) seem to be much simpler when we have only objects of size-X in class_size X. > I prefer your ZS_MAX_ZSPAGE_ORDER increaing approach but as I told > in that thread, we should prepare dynamic creating of sub-page > in zspage. I agree that in general dynamic class page allocation sounds interesting enough. > > > Having said that, I agree your claim that uncompressible pages > > > are pain. I want to handle the problem as multiple-swap apparoach. > > > > zram is not just for swapping. as simple as that. > > Yes, I mean if we have backing storage, we could mitigate the problem > like the mentioned approach. Otherwise, we should solve it in allocator > itself and you suggested the idea and I commented first step. > What's the problem, now? well, I didn't say I have problems. so you want a backing device that will keep only 'bad compression' objects and use zsmalloc to keep there only 'good compression' objects? IOW, no huge classes in zsmalloc at all? well, that can work out. it's a bit strange though that to solve zram-zsmalloc issues we would ask someone to create a additional device. it looks (at least for now) that we can address those issues in zram-zsmalloc entirely; w/o user intervention or a 3rd party device. > > > For that, we should introduce new knob in zram layer like Nitin > > > did and make it configurable so we could solve the problem of > > > single zram-swap system as well as multiple swap system. > > > > a 'bad compression' watermark knob? isn't it an absolutely low level > > thing no one ever should see? > > It's a knob to determine that how to handle incompressible page > in zram layer. For example, admin can tune it to 2048. It means > if we have backing store and compressed ratio is under 50%, > admin want to pass the page into swap storage. If the system > is no backed store, it means admin want to avoid decompress > overhead if the ratio is smaller. I see your point. -ss
[toc] | [prev] | [next] | [standalone]
| From | Sergey Senozhatsky <sergey.senozhatsky.work@gmail.com> |
|---|---|
| Date | 2016-02-22 03:10 +0100 |
| Subject | Re: [RFC][PATCH v2 2/3] zram: use zs_get_huge_class_size_watermark() |
| Message-ID | <r4O6J-6YD-5@gated-at.bofh.it> |
| In reply to | #1339054 |
On (02/22/16 10:59), Sergey Senozhatsky wrote: [..] > > > > Having said that, I agree your claim that uncompressible pages > > > > are pain. I want to handle the problem as multiple-swap apparoach. > > > > > > zram is not just for swapping. as simple as that. > > > > Yes, I mean if we have backing storage, we could mitigate the problem > > like the mentioned approach. Otherwise, we should solve it in allocator > > itself and you suggested the idea and I commented first step. > > What's the problem, now? > > well, I didn't say I have problems. > so you want a backing device that will keep only 'bad compression' > objects and use zsmalloc to keep there only 'good compression' objects? > IOW, no huge classes in zsmalloc at all? hm, in the worst case we can have _for example_ 80+% of writes to be 'bad compression'. that turns zsmalloc into a 3rd wheel, and makes it almost unneeded. hm, may be it's better for now to fix zsmalloc-zram pair. -ss
[toc] | [prev] | [next] | [standalone]
| From | Minchan Kim <minchan@kernel.org> |
|---|---|
| Date | 2016-02-22 04:00 +0100 |
| Subject | Re: [RFC][PATCH v2 2/3] zram: use zs_get_huge_class_size_watermark() |
| Message-ID | <r4OT7-7hh-7@gated-at.bofh.it> |
| In reply to | #1339054 |
On Mon, Feb 22, 2016 at 10:59:12AM +0900, Sergey Senozhatsky wrote: > On (02/22/16 10:27), Minchan Kim wrote: > [..] > > > zram asks to store a PAGE_SIZE sized object, what zsmalloc can > > > possible do about this? > > > > zsmalloc can increase ZS_MAX_ZSPAGE_ORDER or can save metadata in > > the extra space. In fact, I tried interlink approach long time ago. > > For example, class-A -> class-B > > > > A = x, B = (4096 - y) >= x > > > > The problem was class->B zspage consumes memory although there is > > no object in the zspage because class-A object in the extra space > > of class-B pin the class-B zspage. > > I thought about it too -- utilizing 'unused space' to store there > smaller objects. and I think it potentially has more problems. > compaction (and everything) seem to be much simpler when we have only > objects of size-X in class_size X. > > > I prefer your ZS_MAX_ZSPAGE_ORDER increaing approach but as I told > > in that thread, we should prepare dynamic creating of sub-page > > in zspage. > > I agree that in general dynamic class page allocation sounds > interesting enough. > > > > > Having said that, I agree your claim that uncompressible pages > > > > are pain. I want to handle the problem as multiple-swap apparoach. > > > > > > zram is not just for swapping. as simple as that. > > > > Yes, I mean if we have backing storage, we could mitigate the problem > > like the mentioned approach. Otherwise, we should solve it in allocator > > itself and you suggested the idea and I commented first step. > > What's the problem, now? > > well, I didn't say I have problems. > so you want a backing device that will keep only 'bad compression' > objects and use zsmalloc to keep there only 'good compression' objects? > IOW, no huge classes in zsmalloc at all? well, that can work out. it's > a bit strange though that to solve zram-zsmalloc issues we would ask > someone to create a additional device. it looks (at least for now) that > we can address those issues in zram-zsmalloc entirely; w/o user > intervention or a 3rd party device. Agree. That's what I want. zram shouldn't be aware of allocator's internal implementation. IOW, zsmalloc should handle it without exposing any internal limitation. Backing device issue is orthogonal but what I said about thing was it could solve the issue too without exposing zsmalloc's limitation to the zram. Let's summary my points in here. Let's make zsmalloc smarter to reduce wasted space. One of option is dynamic page creation which I agreed. Before the feature, we should test how memory footprint is bigger without the feature if we increase ZS_MAX_ZSPAGE_ORDER. If it's not big, we could go with your patch easily without adding more complex stuff(i.e, dynamic page creation). Please, check max_used_pages rather than mem_used_total for seeing memory footprint at the some moment and test very fragmented scenario (creating files and free part of files) rather than just full coping. If memory footprint is high, we can decide to go dynamic page creation.
[toc] | [prev] | [next] | [standalone]
| From | Sergey Senozhatsky <sergey.senozhatsky.work@gmail.com> |
|---|---|
| Date | 2016-02-22 05:00 +0100 |
| Subject | Re: [RFC][PATCH v2 2/3] zram: use zs_get_huge_class_size_watermark() |
| Message-ID | <r4PPc-83D-7@gated-at.bofh.it> |
| In reply to | #1339086 |
On (02/22/16 11:57), Minchan Kim wrote: [..] > > > Yes, I mean if we have backing storage, we could mitigate the problem > > > like the mentioned approach. Otherwise, we should solve it in allocator > > > itself and you suggested the idea and I commented first step. > > > What's the problem, now? > > > > well, I didn't say I have problems. > > so you want a backing device that will keep only 'bad compression' > > objects and use zsmalloc to keep there only 'good compression' objects? > > IOW, no huge classes in zsmalloc at all? well, that can work out. it's > > a bit strange though that to solve zram-zsmalloc issues we would ask > > someone to create a additional device. it looks (at least for now) that > > we can address those issues in zram-zsmalloc entirely; w/o user > > intervention or a 3rd party device. > > Agree. That's what I want. zram shouldn't be aware of allocator's > internal implementation. IOW, zsmalloc should handle it without > exposing any internal limitation. well, at the same time zram must not dictate what to do. zram simply spoils zsmalloc; it does not offer guaranteed good compression, and it does not let zsmalloc to do it's job. zram has only excuses to be the way it is. the existing zram->zsmalloc dependency looks worse than zsmalloc->zram to me. > Backing device issue is orthogonal but what I said about thing > was it could solve the issue too without exposing zsmalloc's > limitation to the zram. well, backing device would not reduce the amount of pages we request. and that's the priority issue, especially if we are talking about embedded system with a low free pages capability. we would just move huge objects from zsmalloc to backing device. other than that we would still request 1000 (for example) pages to store 1000 objects. it's zsmalloc's "page sharing" that permits us to request less than 1000 pages to store 1000 objects. so yes, I agree, increasing ZS_MAX_ZSPAGE_ORDER and do more tests is the step #1 to take. > Let's summary my points in here. > > Let's make zsmalloc smarter to reduce wasted space. One of option is > dynamic page creation which I agreed. > > Before the feature, we should test how memory footprint is bigger > without the feature if we increase ZS_MAX_ZSPAGE_ORDER. > If it's not big, we could go with your patch easily without adding > more complex stuff(i.e, dynamic page creation). yes, agree. alloc_zspage()/init_zspage() and friends must be the last thing to touch. only if increased ZS_MAX_ZSPAGE_ORDER will turn out not to be good enough. > Please, check max_used_pages rather than mem_used_total for seeing > memory footprint at the some moment and test very fragmented scenario > (creating files and free part of files) rather than just full coping. sure, more tests will follow. -ss
[toc] | [prev] | [next] | [standalone]
| From | Minchan Kim <minchan@kernel.org> |
|---|---|
| Date | 2016-02-22 06:00 +0100 |
| Subject | Re: [RFC][PATCH v2 2/3] zram: use zs_get_huge_class_size_watermark() |
| Message-ID | <r4QLg-ha-5@gated-at.bofh.it> |
| In reply to | #1339118 |
On Mon, Feb 22, 2016 at 12:54:48PM +0900, Sergey Senozhatsky wrote: > On (02/22/16 11:57), Minchan Kim wrote: > [..] > > > > Yes, I mean if we have backing storage, we could mitigate the problem > > > > like the mentioned approach. Otherwise, we should solve it in allocator > > > > itself and you suggested the idea and I commented first step. > > > > What's the problem, now? > > > > > > well, I didn't say I have problems. > > > so you want a backing device that will keep only 'bad compression' > > > objects and use zsmalloc to keep there only 'good compression' objects? > > > IOW, no huge classes in zsmalloc at all? well, that can work out. it's > > > a bit strange though that to solve zram-zsmalloc issues we would ask > > > someone to create a additional device. it looks (at least for now) that > > > we can address those issues in zram-zsmalloc entirely; w/o user > > > intervention or a 3rd party device. > > > > Agree. That's what I want. zram shouldn't be aware of allocator's > > internal implementation. IOW, zsmalloc should handle it without > > exposing any internal limitation. > > well, at the same time zram must not dictate what to do. zram simply spoils > zsmalloc; it does not offer guaranteed good compression, and it does not let > zsmalloc to do it's job. zram has only excuses to be the way it is. > the existing zram->zsmalloc dependency looks worse than zsmalloc->zram to me. I don't get it why you think it's zram->zsmalloc dependency. I already explained. Here it goes, again. Long time ago, zram(i.e, ramzswap) can fallback incompressible page to backed device if it presents and the size was PAGE_SIZE / 2. IOW, if compress ratio is bad than 50%, zram passes the page to backed storage to make memory efficiency. If zram doesn't have backed storage and compress ratio under 25%(ie, short of memory saving) it store pages as uncompressible for avoiding additional *decompress* overhead. Of course, it's arguable whether memory efficiency VS. CPU consumption so we should handle it as another topic. What I want to say in here is it's not dependency between zram and zsmalloc but it was a zram policy for a long time. If it's not good, we can fix it. > > > Backing device issue is orthogonal but what I said about thing > > was it could solve the issue too without exposing zsmalloc's > > limitation to the zram. > > well, backing device would not reduce the amount of pages we request. > and that's the priority issue, especially if we are talking about > embedded system with a low free pages capability. we would just move huge > objects from zsmalloc to backing device. other than that we would still > request 1000 (for example) pages to store 1000 objects. it's zsmalloc's > "page sharing" that permits us to request less than 1000 pages to store > 1000 objects. > > so yes, I agree, increasing ZS_MAX_ZSPAGE_ORDER and do more tests is > the step #1 to take. > > > Let's summary my points in here. > > > > Let's make zsmalloc smarter to reduce wasted space. One of option is > > dynamic page creation which I agreed. > > > > Before the feature, we should test how memory footprint is bigger > > without the feature if we increase ZS_MAX_ZSPAGE_ORDER. > > If it's not big, we could go with your patch easily without adding > > more complex stuff(i.e, dynamic page creation). > > yes, agree. alloc_zspage()/init_zspage() and friends must be the last > thing to touch. only if increased ZS_MAX_ZSPAGE_ORDER will turn out not > to be good enough. > > > Please, check max_used_pages rather than mem_used_total for seeing > > memory footprint at the some moment and test very fragmented scenario > > (creating files and free part of files) rather than just full coping. > > sure, more tests will follow. Thanks.
[toc] | [prev] | [next] | [standalone]
| From | Sergey Senozhatsky <sergey.senozhatsky.work@gmail.com> |
|---|---|
| Date | 2016-02-22 06:10 +0100 |
| Subject | Re: [RFC][PATCH v2 2/3] zram: use zs_get_huge_class_size_watermark() |
| Message-ID | <r4QUW-AB-7@gated-at.bofh.it> |
| In reply to | #1339128 |
On (02/22/16 13:54), Minchan Kim wrote: [..] > > well, at the same time zram must not dictate what to do. zram simply spoils > > zsmalloc; it does not offer guaranteed good compression, and it does not let > > zsmalloc to do it's job. zram has only excuses to be the way it is. > > the existing zram->zsmalloc dependency looks worse than zsmalloc->zram to me. > > I don't get it why you think it's zram->zsmalloc dependency. clearly 'dependency' was simply a wrong word to use, 'enforcement' or 'policy' are better choices here. but you got my point. -ss
[toc] | [prev] | [next] | [standalone]
| From | Sergey Senozhatsky <sergey.senozhatsky@gmail.com> |
|---|---|
| Date | 2016-02-21 19:50 +0100 |
| Subject | [RFC][PATCH v2 1/3] mm/zsmalloc: introduce zs_get_huge_class_size_watermark() |
| Message-ID | <r4HeW-1KO-25@gated-at.bofh.it> |
| In reply to | #1338850 |
From: Sergey Senozhatsky <sergey.senozhatsky.work@gmail.com>
zsmalloc knows the watermark after which classes are considered
to be ->huge -- every object stored consumes the entire zspage (which
consist of a single order-0 page). On x86_64, PAGE_SHIFT 12 box, the
first non-huge class size is 3264, so starting down from size 3264,
objects share page(-s) and thus minimize memory wastage.
zram, however, has its own statically defined watermark for `bad'
compression "3 * PAGE_SIZE / 4 = 3072", and stores every object
larger than this watermark (3072) as a PAGE_SIZE, object, IOW,
to a ->huge class, this results in increased memory consumption and
memory wastage. (With a small exception: 3264 bytes class. zs_malloc()
adds ZS_HANDLE_SIZE to the object's size, so some objects can pass
3072 bytes and get_size_class_index(size) will return 3264 bytes size
class).
Introduce a zs_get_huge_class_size_watermark() function which tells
the size of a first non-huge class; so zram now can store objects
to ->huge clases only when those objects have sizes greater than
huge_class_size_watermark.
Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
---
include/linux/zsmalloc.h | 2 ++
mm/zsmalloc.c | 14 ++++++++++++++
2 files changed, 16 insertions(+)
diff --git a/include/linux/zsmalloc.h b/include/linux/zsmalloc.h
index 34eb160..45dcb51 100644
--- a/include/linux/zsmalloc.h
+++ b/include/linux/zsmalloc.h
@@ -55,4 +55,6 @@ unsigned long zs_get_total_pages(struct zs_pool *pool);
unsigned long zs_compact(struct zs_pool *pool);
void zs_pool_stats(struct zs_pool *pool, struct zs_pool_stats *stats);
+
+int zs_get_huge_class_size_watermark(void);
#endif
diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c
index 43e4cbc..e7f10bd 100644
--- a/mm/zsmalloc.c
+++ b/mm/zsmalloc.c
@@ -188,6 +188,11 @@ static struct dentry *zs_stat_root;
static int zs_size_classes;
/*
+ * All classes above this class_size are huge classes
+ */
+static int huge_class_size_watermark;
+
+/*
* We assign a page to ZS_ALMOST_EMPTY fullness group when:
* n <= N / f, where
* n = number of allocated objects
@@ -1241,6 +1246,12 @@ unsigned long zs_get_total_pages(struct zs_pool *pool)
}
EXPORT_SYMBOL_GPL(zs_get_total_pages);
+int zs_get_huge_class_size_watermark(void)
+{
+ return huge_class_size_watermark;
+}
+EXPORT_SYMBOL_GPL(zs_get_huge_class_size_watermark);
+
/**
* zs_map_object - get address of allocated object from handle.
* @pool: pool from which the object was allocated
@@ -1942,10 +1953,13 @@ struct zs_pool *zs_create_pool(const char *name, gfp_t flags)
if (pages_per_zspage == 1 &&
get_maxobj_per_zspage(size, pages_per_zspage) == 1)
class->huge = true;
+
spin_lock_init(&class->lock);
pool->size_class[i] = class;
prev_class = class;
+ if (!class->huge && !huge_class_size_watermark)
+ huge_class_size_watermark = size - ZS_HANDLE_SIZE;
}
pool->flags = flags;
--
2.7.1
[toc] | [prev] | [next] | [standalone]
| From | Sergey Senozhatsky <sergey.senozhatsky@gmail.com> |
|---|---|
| Date | 2016-02-21 20:00 +0100 |
| Subject | [RFC][PATCH v2 3/3] mm/zsmalloc: increase ZS_MAX_PAGES_PER_ZSPAGE |
| Message-ID | <r4HoC-1OF-13@gated-at.bofh.it> |
| In reply to | #1338850 |
From: Sergey Senozhatsky <sergey.senozhatsky.work@gmail.com> The existing limit of max 4 pages per zspage sets a tight limit on ->huge classes, which results in increased memory consumption. On x86_64, PAGE_SHIFT 12, ->huge class_size range is 3280-4096. The problem with ->huge classes is that in most of the cases they waste memory, because each ->huge zspage has only one order-0 page and can store only one object. For instance, we store 3408 bytes objects as PAGE_SIZE objects, while in fact each of those objects has 4096 - 3408 = 688 bytes of spare space, so we need to store 5 objects to have enough spare space to save the 6th objects with out requesting a new order-0 page. In general, turning a ->huge class into a normal will save PAGE_SIZE bytes every time "PAGE_SIZE/(PAGE_SIZE - CLASS_SIZE)"-th object is stored. The maximum number of order-0 pages in zspages is limited by ZS_MAX_ZSPAGE_ORDER (zspage can consist of up to 1<<ZS_MAX_ZSPAGE_ORDER pages). Increasing ZS_MAX_ZSPAGE_ORDER permits us to have less ->huge classes, because some of them now can form a 'normal' zspage consisting of several order-0 pages. We can't increase ZS_MAX_ZSPAGE_ORDER on every platform: 32-bit PAE/LPAE and PAGE_SHIFT 16 kernels don't have enough bits left in OBJ_INDEX_BITS. Other than that, we can increase ZS_MAX_ZSPAGE_ORDER to 4. This will change the ->huge classes range (on PAGE_SHIFT 12 systems) from 3280-4096 to 3856-4096. This will increase density and reduce memory wastage/usage. TESTS (ZS_MAX_ZSPAGE_ORDER 4) ============================= showing only bottom of /sys/kernel/debug/zsmalloc/zram0/classes class size almost_full almost_empty obj_allocated obj_used pages_used ======================================================================== 1) compile glibc -j8 BASE ... 168 2720 0 14 4500 4479 3000 190 3072 0 15 3016 2986 2262 202 3264 2 2 70 61 56 254 4096 0 0 40213 40213 40213 Total 63 247 155676 153957 74955 PATCHED ... 191 3088 1 1 130 116 100 192 3104 1 1 119 103 91 194 3136 1 1 260 254 200 197 3184 0 3 522 503 406 199 3216 2 3 350 320 275 200 3232 0 2 114 93 90 202 3264 2 2 210 202 168 206 3328 1 5 464 418 377 207 3344 1 2 121 108 99 208 3360 0 3 153 119 126 211 3408 2 4 360 341 300 212 3424 1 2 133 112 112 214 3456 0 2 182 170 154 217 3504 0 4 217 200 186 219 3536 0 3 135 108 117 222 3584 0 3 144 132 126 223 3600 1 1 51 35 45 225 3632 1 2 108 99 96 228 3680 0 2 140 129 126 230 3712 0 3 110 94 100 232 3744 1 2 132 113 121 234 3776 1 2 143 128 132 235 3792 0 3 112 81 104 236 3808 0 2 75 62 70 238 3840 0 2 112 91 105 254 4096 0 0 36112 36112 36112 Total 127 228 158342 154050 73884 == Consumed 74955-73884 = 1071 less order-0 pages. 2) copy linux-next directory (with object files, 2.5G) BASE ... 190 3072 0 1 9092 9091 6819 202 3264 0 0 240 240 192 254 4096 0 0 360304 360304 360304 Total 34 83 687545 686443 480962 PATCHED ... 191 3088 0 1 455 449 350 192 3104 1 0 425 421 325 194 3136 1 0 936 935 720 197 3184 0 1 1539 1532 1197 199 3216 0 1 1148 1142 902 200 3232 0 1 570 560 450 202 3264 1 0 1245 1244 996 206 3328 0 1 2896 2887 2353 207 3344 0 0 825 825 675 208 3360 0 1 850 845 700 211 3408 0 1 2694 2692 2245 212 3424 0 1 931 922 784 214 3456 1 0 1924 1923 1628 217 3504 0 0 2968 2968 2544 219 3536 0 1 2220 2209 1924 222 3584 0 1 3120 3114 2730 223 3600 0 1 1088 1081 960 225 3632 0 1 2133 2130 1896 228 3680 0 1 3340 3334 3006 230 3712 0 1 2035 2025 1850 232 3744 0 1 1980 1972 1815 234 3776 0 1 2015 2009 1860 235 3792 0 1 1022 1013 949 236 3808 1 0 960 958 896 238 3840 0 0 1968 1968 1845 254 4096 0 0 319370 319370 319370 Total 71 137 687877 684436 471265 Consumed 480962 - 471265 = 9697 less order-0 pages. 3) Run a test script (storing text files of various sizes, binary files of various sizes) cat /sys/block/zram0/mm_stat column 3 is zs_get_total_pages() << PAGE_SHIFT BASE 614477824 425627436 436678656 0 436678656 539608 0 1 614526976 425709397 436813824 0 436813824 539580 0 1 614502400 425694649 436719616 0 436719616 539585 0 1 614510592 425658934 436723712 0 436723712 539583 0 1 614477824 425685915 436740096 0 436740096 539589 0 1 PATCHED 614543360 387655040 395124736 0 395124736 539577 0 1 614445056 387667599 395206656 0 395206656 539614 0 1 614477824 387686121 395059200 0 395059200 539589 0 1 614461440 387748115 395075584 0 395075584 539592 0 1 614486016 387670405 395022336 0 395022336 539588 0 1 == Consumed around 39MB less memory. P.S. on x86_64, minimum LZO compressed buffer size seems to be around 44 bytes. zsmalloc adds ZS_HANDLE_SIZE (sizeof(unsigned long)) to the object's size in zs_malloc(). Thus, 32 bytes and 48 bytes classes are unreachable by LZO on x86_64 PAGE_SHIFT 12 platforms. LZ4, however, seems to have a minimum compressed buffer size around 26 bytes. So, once again, on x86_64, 32 bytes class is unreachable, but we need to keep 48 bytes size class. In he worst case, in theory, if we ever run out of bits in OBJ_INDEX_BITS we can drop 32 bytes and (well, with some consideration) 48 bytes classes, IOW, do ZS_MIN_ALLOC_SIZE << 1. Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com> --- mm/zsmalloc.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c index e7f10bd..ab9ed8f 100644 --- a/mm/zsmalloc.c +++ b/mm/zsmalloc.c @@ -73,13 +73,6 @@ */ #define ZS_ALIGN 8 -/* - * A single 'zspage' is composed of up to 2^N discontiguous 0-order (single) - * pages. ZS_MAX_ZSPAGE_ORDER defines upper limit on N. - */ -#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)) /* @@ -96,6 +89,7 @@ #ifndef MAX_PHYSMEM_BITS #ifdef CONFIG_HIGHMEM64G #define MAX_PHYSMEM_BITS 36 +#define ZS_MAX_ZSPAGE_ORDER 2 #else /* !CONFIG_HIGHMEM64G */ /* * If this definition of MAX_PHYSMEM_BITS is used, OBJ_INDEX_BITS will just @@ -104,9 +98,30 @@ #define MAX_PHYSMEM_BITS BITS_PER_LONG #endif #endif + #define _PFN_BITS (MAX_PHYSMEM_BITS - PAGE_SHIFT) /* + * We don't have enough bits in OBJ_INDEX_BITS on HIGHMEM64G and + * PAGE_SHIFT 16 systems to have huge ZS_MAX_ZSPAGE_ORDER there. + * This will significantly increase ZS_MIN_ALLOC_SIZE and drop a + * number of important (frequently used in general) size classes. + */ +#if PAGE_SHIFT > 14 +#define ZS_MAX_ZSPAGE_ORDER 2 +#endif + +#ifndef ZS_MAX_ZSPAGE_ORDER +#define ZS_MAX_ZSPAGE_ORDER 4 +#endif + +/* + * A single 'zspage' is composed of up to 2^N discontiguous 0-order (single) + * pages. ZS_MAX_ZSPAGE_ORDER defines upper limit on N. + */ +#define ZS_MAX_PAGES_PER_ZSPAGE (_AC(1, UL) << ZS_MAX_ZSPAGE_ORDER) + +/* * Memory for allocating for handle keeps object position by * encoding <page, obj_idx> and the encoded value has a room * in least bit(ie, look at obj_to_location). -- 2.7.1
[toc] | [prev] | [next] | [standalone]
| From | Minchan Kim <minchan@kernel.org> |
|---|---|
| Date | 2016-02-22 01:30 +0100 |
| Subject | Re: [RFC][PATCH v2 3/3] mm/zsmalloc: increase ZS_MAX_PAGES_PER_ZSPAGE |
| Message-ID | <r4MxY-5PB-7@gated-at.bofh.it> |
| In reply to | #1338956 |
On Sun, Feb 21, 2016 at 10:27:54PM +0900, Sergey Senozhatsky wrote: > From: Sergey Senozhatsky <sergey.senozhatsky.work@gmail.com> > > The existing limit of max 4 pages per zspage sets a tight limit > on ->huge classes, which results in increased memory consumption. > > On x86_64, PAGE_SHIFT 12, ->huge class_size range is 3280-4096. > The problem with ->huge classes is that in most of the cases they > waste memory, because each ->huge zspage has only one order-0 page > and can store only one object. > > For instance, we store 3408 bytes objects as PAGE_SIZE objects, > while in fact each of those objects has 4096 - 3408 = 688 bytes > of spare space, so we need to store 5 objects to have enough spare > space to save the 6th objects with out requesting a new order-0 page. > In general, turning a ->huge class into a normal will save PAGE_SIZE > bytes every time "PAGE_SIZE/(PAGE_SIZE - CLASS_SIZE)"-th object is > stored. > > The maximum number of order-0 pages in zspages is limited by > ZS_MAX_ZSPAGE_ORDER (zspage can consist of up to 1<<ZS_MAX_ZSPAGE_ORDER > pages). Increasing ZS_MAX_ZSPAGE_ORDER permits us to have less ->huge > classes, because some of them now can form a 'normal' zspage consisting > of several order-0 pages. > > We can't increase ZS_MAX_ZSPAGE_ORDER on every platform: 32-bit > PAE/LPAE and PAGE_SHIFT 16 kernels don't have enough bits left in > OBJ_INDEX_BITS. Other than that, we can increase ZS_MAX_ZSPAGE_ORDER > to 4. This will change the ->huge classes range (on PAGE_SHIFT 12 > systems) from 3280-4096 to 3856-4096. This will increase density > and reduce memory wastage/usage. I tempted it several times with same reason you pointed out. But my worry was that if we increase ZS_MAX_ZSPAGE_ORDER, zram can consume more memory because we need several pages chain to populate just a object. Even, at that time, we didn't have compaction scheme so fragmentation of object in zspage is huge pain to waste memory. Now, we have compaction facility so fragment of object might not be a severe problem but still painful to allocate 16 pages to store 3408 byte. So, if we want to increase ZS_MAX_ZSPAGE_ORDER, first of all, we should prepare dynamic creating of sub-page of zspage, I think and more smart compaction to minimize wasted memory. > > TESTS (ZS_MAX_ZSPAGE_ORDER 4) > ============================= > > showing only bottom of /sys/kernel/debug/zsmalloc/zram0/classes > > class size almost_full almost_empty obj_allocated obj_used pages_used > ======================================================================== > > 1) compile glibc -j8 > > BASE > ... > 168 2720 0 14 4500 4479 3000 > 190 3072 0 15 3016 2986 2262 > 202 3264 2 2 70 61 56 > 254 4096 0 0 40213 40213 40213 > > Total 63 247 155676 153957 74955 > > PATCHED > ... > 191 3088 1 1 130 116 100 > 192 3104 1 1 119 103 91 > 194 3136 1 1 260 254 200 > 197 3184 0 3 522 503 406 > 199 3216 2 3 350 320 275 > 200 3232 0 2 114 93 90 > 202 3264 2 2 210 202 168 > 206 3328 1 5 464 418 377 > 207 3344 1 2 121 108 99 > 208 3360 0 3 153 119 126 > 211 3408 2 4 360 341 300 > 212 3424 1 2 133 112 112 > 214 3456 0 2 182 170 154 > 217 3504 0 4 217 200 186 > 219 3536 0 3 135 108 117 > 222 3584 0 3 144 132 126 > 223 3600 1 1 51 35 45 > 225 3632 1 2 108 99 96 > 228 3680 0 2 140 129 126 > 230 3712 0 3 110 94 100 > 232 3744 1 2 132 113 121 > 234 3776 1 2 143 128 132 > 235 3792 0 3 112 81 104 > 236 3808 0 2 75 62 70 > 238 3840 0 2 112 91 105 > 254 4096 0 0 36112 36112 36112 > > Total 127 228 158342 154050 73884 > > == Consumed 74955-73884 = 1071 less order-0 pages. > > 2) copy linux-next directory (with object files, 2.5G) > > BASE > ... > 190 3072 0 1 9092 9091 6819 > 202 3264 0 0 240 240 192 > 254 4096 0 0 360304 360304 360304 > > Total 34 83 687545 686443 480962 > > PATCHED > ... > 191 3088 0 1 455 449 350 > 192 3104 1 0 425 421 325 > 194 3136 1 0 936 935 720 > 197 3184 0 1 1539 1532 1197 > 199 3216 0 1 1148 1142 902 > 200 3232 0 1 570 560 450 > 202 3264 1 0 1245 1244 996 > 206 3328 0 1 2896 2887 2353 > 207 3344 0 0 825 825 675 > 208 3360 0 1 850 845 700 > 211 3408 0 1 2694 2692 2245 > 212 3424 0 1 931 922 784 > 214 3456 1 0 1924 1923 1628 > 217 3504 0 0 2968 2968 2544 > 219 3536 0 1 2220 2209 1924 > 222 3584 0 1 3120 3114 2730 > 223 3600 0 1 1088 1081 960 > 225 3632 0 1 2133 2130 1896 > 228 3680 0 1 3340 3334 3006 > 230 3712 0 1 2035 2025 1850 > 232 3744 0 1 1980 1972 1815 > 234 3776 0 1 2015 2009 1860 > 235 3792 0 1 1022 1013 949 > 236 3808 1 0 960 958 896 > 238 3840 0 0 1968 1968 1845 > 254 4096 0 0 319370 319370 319370 > > Total 71 137 687877 684436 471265 > > Consumed 480962 - 471265 = 9697 less order-0 pages. > > 3) Run a test script (storing text files of various sizes, binary files > of various sizes) > > cat /sys/block/zram0/mm_stat column 3 is zs_get_total_pages() << PAGE_SHIFT > > BASE > 614477824 425627436 436678656 0 436678656 539608 0 1 > 614526976 425709397 436813824 0 436813824 539580 0 1 > 614502400 425694649 436719616 0 436719616 539585 0 1 > 614510592 425658934 436723712 0 436723712 539583 0 1 > 614477824 425685915 436740096 0 436740096 539589 0 1 > > PATCHED > 614543360 387655040 395124736 0 395124736 539577 0 1 > 614445056 387667599 395206656 0 395206656 539614 0 1 > 614477824 387686121 395059200 0 395059200 539589 0 1 > 614461440 387748115 395075584 0 395075584 539592 0 1 > 614486016 387670405 395022336 0 395022336 539588 0 1 > > == Consumed around 39MB less memory. > > P.S. on x86_64, minimum LZO compressed buffer size seems to be around 44 > bytes. zsmalloc adds ZS_HANDLE_SIZE (sizeof(unsigned long)) to the object's > size in zs_malloc(). Thus, 32 bytes and 48 bytes classes are unreachable by > LZO on x86_64 PAGE_SHIFT 12 platforms. LZ4, however, seems to have a minimum > compressed buffer size around 26 bytes. So, once again, on x86_64, 32 bytes > class is unreachable, but we need to keep 48 bytes size class. In he worst > case, in theory, if we ever run out of bits in OBJ_INDEX_BITS we can drop 32 > bytes and (well, with some consideration) 48 bytes classes, IOW, do > ZS_MIN_ALLOC_SIZE << 1. > > Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com> > --- > mm/zsmalloc.c | 29 ++++++++++++++++++++++------- > 1 file changed, 22 insertions(+), 7 deletions(-) > > diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c > index e7f10bd..ab9ed8f 100644 > --- a/mm/zsmalloc.c > +++ b/mm/zsmalloc.c > @@ -73,13 +73,6 @@ > */ > #define ZS_ALIGN 8 > > -/* > - * A single 'zspage' is composed of up to 2^N discontiguous 0-order (single) > - * pages. ZS_MAX_ZSPAGE_ORDER defines upper limit on N. > - */ > -#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)) > > /* > @@ -96,6 +89,7 @@ > #ifndef MAX_PHYSMEM_BITS > #ifdef CONFIG_HIGHMEM64G > #define MAX_PHYSMEM_BITS 36 > +#define ZS_MAX_ZSPAGE_ORDER 2 > #else /* !CONFIG_HIGHMEM64G */ > /* > * If this definition of MAX_PHYSMEM_BITS is used, OBJ_INDEX_BITS will just > @@ -104,9 +98,30 @@ > #define MAX_PHYSMEM_BITS BITS_PER_LONG > #endif > #endif > + > #define _PFN_BITS (MAX_PHYSMEM_BITS - PAGE_SHIFT) > > /* > + * We don't have enough bits in OBJ_INDEX_BITS on HIGHMEM64G and > + * PAGE_SHIFT 16 systems to have huge ZS_MAX_ZSPAGE_ORDER there. > + * This will significantly increase ZS_MIN_ALLOC_SIZE and drop a > + * number of important (frequently used in general) size classes. > + */ > +#if PAGE_SHIFT > 14 > +#define ZS_MAX_ZSPAGE_ORDER 2 > +#endif > + > +#ifndef ZS_MAX_ZSPAGE_ORDER > +#define ZS_MAX_ZSPAGE_ORDER 4 > +#endif > + > +/* > + * A single 'zspage' is composed of up to 2^N discontiguous 0-order (single) > + * pages. ZS_MAX_ZSPAGE_ORDER defines upper limit on N. > + */ > +#define ZS_MAX_PAGES_PER_ZSPAGE (_AC(1, UL) << ZS_MAX_ZSPAGE_ORDER) > + > +/* > * Memory for allocating for handle keeps object position by > * encoding <page, obj_idx> and the encoded value has a room > * in least bit(ie, look at obj_to_location). > -- > 2.7.1 >
[toc] | [prev] | [next] | [standalone]
| From | Sergey Senozhatsky <sergey.senozhatsky.work@gmail.com> |
|---|---|
| Date | 2016-02-22 01:50 +0100 |
| Subject | Re: [RFC][PATCH v2 3/3] mm/zsmalloc: increase ZS_MAX_PAGES_PER_ZSPAGE |
| Message-ID | <r4MRk-5YM-21@gated-at.bofh.it> |
| In reply to | #1339029 |
On (02/22/16 09:25), Minchan Kim wrote: [..] > I tempted it several times with same reason you pointed out. > But my worry was that if we increase ZS_MAX_ZSPAGE_ORDER, zram can > consume more memory because we need several pages chain to populate > just a object. Even, at that time, we didn't have compaction scheme > so fragmentation of object in zspage is huge pain to waste memory. well, the thing is -- we end up requesting less pages after all, so zsmalloc has better chances to survive. for example, gcc5 compilation test BASE 168 2720 0 1 115833 115831 77222 2 190 3072 0 1 109708 109707 82281 3 202 3264 0 5 1910 1895 1528 4 254 4096 0 0 380174 380174 380174 1 Total 44 285 1621495 1618234 891703 PATCHED 192 3104 1 0 3740 3737 2860 13 194 3136 0 1 7215 7208 5550 10 197 3184 1 0 11151 11150 8673 7 199 3216 0 1 9310 9304 7315 11 200 3232 0 1 4731 4717 3735 15 202 3264 0 1 8400 8396 6720 4 206 3328 0 1 22064 22051 17927 13 207 3344 0 1 4884 4877 3996 9 208 3360 0 1 4420 4415 3640 14 211 3408 0 1 11250 11246 9375 5 212 3424 1 0 3344 3343 2816 16 214 3456 0 2 7345 7329 6215 11 217 3504 0 1 10801 10797 9258 6 219 3536 0 1 5295 5289 4589 13 222 3584 0 0 6008 6008 5257 7 223 3600 0 1 1530 1518 1350 15 225 3632 0 1 3519 3514 3128 8 228 3680 0 1 3990 3985 3591 9 230 3712 0 2 2167 2151 1970 10 232 3744 1 2 1848 1835 1694 11 234 3776 0 2 1404 1384 1296 12 235 3792 0 2 672 654 624 13 236 3808 1 2 615 592 574 14 238 3840 1 2 1120 1098 1050 15 254 4096 0 0 241824 241824 241824 1 Total 129 489 1627756 1618193 850147 that's 891703 - 850147 = 41556 less pages. or 162MB less memory used. 41556 less pages means that zsmalloc had 41556 less chances to fail. > Now, we have compaction facility so fragment of object might not > be a severe problem but still painful to allocate 16 pages to store > 3408 byte. So, if we want to increase ZS_MAX_ZSPAGE_ORDER, > first of all, we should prepare dynamic creating of sub-page of > zspage, I think and more smart compaction to minimize wasted memory. well, I agree, but given that we allocate less pages, do we really want to introduce this complexity at this point? -ss
[toc] | [prev] | [next] | [standalone]
| From | Minchan Kim <minchan@kernel.org> |
|---|---|
| Date | 2016-02-22 02:40 +0100 |
| Subject | Re: [RFC][PATCH v2 3/3] mm/zsmalloc: increase ZS_MAX_PAGES_PER_ZSPAGE |
| Message-ID | <r4NDI-6z9-9@gated-at.bofh.it> |
| In reply to | #1339039 |
On Mon, Feb 22, 2016 at 09:47:58AM +0900, Sergey Senozhatsky wrote: > On (02/22/16 09:25), Minchan Kim wrote: > [..] > > I tempted it several times with same reason you pointed out. > > But my worry was that if we increase ZS_MAX_ZSPAGE_ORDER, zram can > > consume more memory because we need several pages chain to populate > > just a object. Even, at that time, we didn't have compaction scheme > > so fragmentation of object in zspage is huge pain to waste memory. > > well, the thing is -- we end up requesting less pages after all, so > zsmalloc has better chances to survive. for example, gcc5 compilation test Indeed. I saw your test result. > > BASE > > 168 2720 0 1 115833 115831 77222 2 > 190 3072 0 1 109708 109707 82281 3 > 202 3264 0 5 1910 1895 1528 4 > 254 4096 0 0 380174 380174 380174 1 > > Total 44 285 1621495 1618234 891703 > > > PATCHED > > 192 3104 1 0 3740 3737 2860 13 > 194 3136 0 1 7215 7208 5550 10 > 197 3184 1 0 11151 11150 8673 7 > 199 3216 0 1 9310 9304 7315 11 > 200 3232 0 1 4731 4717 3735 15 > 202 3264 0 1 8400 8396 6720 4 > 206 3328 0 1 22064 22051 17927 13 > 207 3344 0 1 4884 4877 3996 9 > 208 3360 0 1 4420 4415 3640 14 > 211 3408 0 1 11250 11246 9375 5 > 212 3424 1 0 3344 3343 2816 16 > 214 3456 0 2 7345 7329 6215 11 > 217 3504 0 1 10801 10797 9258 6 > 219 3536 0 1 5295 5289 4589 13 > 222 3584 0 0 6008 6008 5257 7 > 223 3600 0 1 1530 1518 1350 15 > 225 3632 0 1 3519 3514 3128 8 > 228 3680 0 1 3990 3985 3591 9 > 230 3712 0 2 2167 2151 1970 10 > 232 3744 1 2 1848 1835 1694 11 > 234 3776 0 2 1404 1384 1296 12 > 235 3792 0 2 672 654 624 13 > 236 3808 1 2 615 592 574 14 > 238 3840 1 2 1120 1098 1050 15 > 254 4096 0 0 241824 241824 241824 1 > > Total 129 489 1627756 1618193 850147 > > > that's 891703 - 850147 = 41556 less pages. or 162MB less memory used. > 41556 less pages means that zsmalloc had 41556 less chances to fail. Let's think swap-case which is more important for zram now. As you know, most of usecase are swap in embedded world. Do we really need 16 pages allocator for just less PAGE_SIZE objet at the moment which is really heavy memory pressure? > > > > Now, we have compaction facility so fragment of object might not > > be a severe problem but still painful to allocate 16 pages to store > > 3408 byte. So, if we want to increase ZS_MAX_ZSPAGE_ORDER, > > first of all, we should prepare dynamic creating of sub-page of > > zspage, I think and more smart compaction to minimize wasted memory. > > well, I agree, but given that we allocate less pages, do we really want to > introduce this complexity at this point? I agree with you. Before dynamic subpage chaining feature, we need lots of testing in heavy memory pressure with zram-swap. However, I think the feature itself is good to have in the future. :) > > -ss
[toc] | [prev] | [next] | [standalone]
| From | Sergey Senozhatsky <sergey.senozhatsky.work@gmail.com> |
|---|---|
| Date | 2016-02-22 03:10 +0100 |
| Subject | Re: [RFC][PATCH v2 3/3] mm/zsmalloc: increase ZS_MAX_PAGES_PER_ZSPAGE |
| Message-ID | <r4O6J-6YD-7@gated-at.bofh.it> |
| In reply to | #1339047 |
On (02/22/16 10:34), Minchan Kim wrote: [..] > > > I tempted it several times with same reason you pointed out. > > > But my worry was that if we increase ZS_MAX_ZSPAGE_ORDER, zram can > > > consume more memory because we need several pages chain to populate > > > just a object. Even, at that time, we didn't have compaction scheme > > > so fragmentation of object in zspage is huge pain to waste memory. > > > > well, the thing is -- we end up requesting less pages after all, so > > zsmalloc has better chances to survive. for example, gcc5 compilation test > > Indeed. I saw your test result. [..] > > Total 129 489 1627756 1618193 850147 > > > > > > that's 891703 - 850147 = 41556 less pages. or 162MB less memory used. > > 41556 less pages means that zsmalloc had 41556 less chances to fail. > > > Let's think swap-case which is more important for zram now. As you know, > most of usecase are swap in embedded world. > Do we really need 16 pages allocator for just less PAGE_SIZE objet > at the moment which is really heavy memory pressure? I'll take a look at dynamic class page addition. -ss
[toc] | [prev] | [next] | [standalone]
| From | Minchan Kim <minchan@kernel.org> |
|---|---|
| Date | 2016-02-22 03:40 +0100 |
| Subject | Re: [RFC][PATCH v2 3/3] mm/zsmalloc: increase ZS_MAX_PAGES_PER_ZSPAGE |
| Message-ID | <r4OzL-7aj-11@gated-at.bofh.it> |
| In reply to | #1339065 |
On Mon, Feb 22, 2016 at 11:01:13AM +0900, Sergey Senozhatsky wrote: > On (02/22/16 10:34), Minchan Kim wrote: > [..] > > > > I tempted it several times with same reason you pointed out. > > > > But my worry was that if we increase ZS_MAX_ZSPAGE_ORDER, zram can > > > > consume more memory because we need several pages chain to populate > > > > just a object. Even, at that time, we didn't have compaction scheme > > > > so fragmentation of object in zspage is huge pain to waste memory. > > > > > > well, the thing is -- we end up requesting less pages after all, so > > > zsmalloc has better chances to survive. for example, gcc5 compilation test > > > > Indeed. I saw your test result. > > > [..] > > > Total 129 489 1627756 1618193 850147 > > > > > > > > > that's 891703 - 850147 = 41556 less pages. or 162MB less memory used. > > > 41556 less pages means that zsmalloc had 41556 less chances to fail. > > > > > > Let's think swap-case which is more important for zram now. As you know, > > most of usecase are swap in embedded world. > > Do we really need 16 pages allocator for just less PAGE_SIZE objet > > at the moment which is really heavy memory pressure? > > I'll take a look at dynamic class page addition. Thanks, Sergey. Just a note: I am preparing zsmalloc migration now and almost done so I hope I can send it within two weeks. In there, I changed a lot of things in zsmalloc, page chaining, struct page fields usecases and locking scheme and so on. The zsmalloc fragment/migration is really painful now so we should solve it first so I hope you help to review that and let's go further dynamic chaining after that, please. :)
[toc] | [prev] | [next] | [standalone]
| From | Sergey Senozhatsky <sergey.senozhatsky.work@gmail.com> |
|---|---|
| Date | 2016-02-22 05:00 +0100 |
| Subject | Re: [RFC][PATCH v2 3/3] mm/zsmalloc: increase ZS_MAX_PAGES_PER_ZSPAGE |
| Message-ID | <r4PPc-83D-11@gated-at.bofh.it> |
| In reply to | #1339076 |
On (02/22/16 11:34), Minchan Kim wrote: [..] > > I'll take a look at dynamic class page addition. > > Thanks, Sergey. > > Just a note: > > I am preparing zsmalloc migration now and almost done so I hope > I can send it within two weeks. In there, I changed a lot of > things in zsmalloc, page chaining, struct page fields usecases > and locking scheme and so on. The zsmalloc fragment/migration > is really painful now so we should solve it first so I hope > you help to review that and let's go further dynamic chaining > after that, please. :) oh, sure. so let's keep dynamic page allocation out of sight for now. I'll do more tests with the increase ORDER and if it's OK then hopefully we can just merge it, it's quite simple and shouldn't interfere with any of the changes you are about to introduce. -ss
[toc] | [prev] | [next] | [standalone]
| From | Minchan Kim <minchan@kernel.org> |
|---|---|
| Date | 2016-02-22 05:50 +0100 |
| Subject | Re: [RFC][PATCH v2 3/3] mm/zsmalloc: increase ZS_MAX_PAGES_PER_ZSPAGE |
| Message-ID | <r4QBz-dr-1@gated-at.bofh.it> |
| In reply to | #1339120 |
On Mon, Feb 22, 2016 at 12:59:54PM +0900, Sergey Senozhatsky wrote: > On (02/22/16 11:34), Minchan Kim wrote: > [..] > > > I'll take a look at dynamic class page addition. > > > > Thanks, Sergey. > > > > Just a note: > > > > I am preparing zsmalloc migration now and almost done so I hope > > I can send it within two weeks. In there, I changed a lot of > > things in zsmalloc, page chaining, struct page fields usecases > > and locking scheme and so on. The zsmalloc fragment/migration > > is really painful now so we should solve it first so I hope > > you help to review that and let's go further dynamic chaining > > after that, please. :) > > oh, sure. > > so let's keep dynamic page allocation out of sight for now. > I'll do more tests with the increase ORDER and if it's OK then > hopefully we can just merge it, it's quite simple and shouldn't > interfere with any of the changes you are about to introduce. Thanks. And as another idea, we could try fallback approach that we couldn't meet nr_pages to minimize wastage so let's fallback to order-0 page like as-is. It will enhance, at least than now with small-amount of code compared to dynmaic page allocation.
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | linux.kernel
csiph-web