Merge second patchbomb from Andrew Morton: - the rest of MM - various misc bits - add ability to run /sbin/reboot at reboot time - printk/vsprintf changes - fiddle with seq_printf() return value * akpm: (114 commits) parisc: remove use of seq_printf return value lru_cache: remove use of seq_printf return value tracing: remove use of seq_printf return value cgroup: remove use of seq_printf return value proc: remove use of seq_printf return value s390: remove use of seq_printf return value cris fasttimer: remove use of seq_printf return value cris: remove use of seq_printf return value openrisc: remove use of seq_printf return value ARM: plat-pxa: remove use of seq_printf return value nios2: cpuinfo: remove use of seq_printf return value microblaze: mb: remove use of seq_printf return value ipc: remove use of seq_printf return value rtc: remove use of seq_printf return value power: wakeup: remove use of seq_printf return value x86: mtrr: if: remove use of seq_printf return value linux/bitmap.h: improve BITMAP_{LAST,FIRST}_WORD_MASK MAINTAINERS: CREDITS: remove Stefano Brivio from B43 .mailmap: add Ricardo Ribalda CREDITS: add Ricardo Ribalda Delgado ...tirimbino
commit
eea3a00264
@ -0,0 +1,119 @@ |
||||
What: /sys/block/zram<id>/num_reads |
||||
Date: August 2015 |
||||
Contact: Sergey Senozhatsky <sergey.senozhatsky@gmail.com> |
||||
Description: |
||||
The num_reads file is read-only and specifies the number of |
||||
reads (failed or successful) done on this device. |
||||
Now accessible via zram<id>/stat node. |
||||
|
||||
What: /sys/block/zram<id>/num_writes |
||||
Date: August 2015 |
||||
Contact: Sergey Senozhatsky <sergey.senozhatsky@gmail.com> |
||||
Description: |
||||
The num_writes file is read-only and specifies the number of |
||||
writes (failed or successful) done on this device. |
||||
Now accessible via zram<id>/stat node. |
||||
|
||||
What: /sys/block/zram<id>/invalid_io |
||||
Date: August 2015 |
||||
Contact: Sergey Senozhatsky <sergey.senozhatsky@gmail.com> |
||||
Description: |
||||
The invalid_io file is read-only and specifies the number of |
||||
non-page-size-aligned I/O requests issued to this device. |
||||
Now accessible via zram<id>/io_stat node. |
||||
|
||||
What: /sys/block/zram<id>/failed_reads |
||||
Date: August 2015 |
||||
Contact: Sergey Senozhatsky <sergey.senozhatsky@gmail.com> |
||||
Description: |
||||
The failed_reads file is read-only and specifies the number of |
||||
failed reads happened on this device. |
||||
Now accessible via zram<id>/io_stat node. |
||||
|
||||
What: /sys/block/zram<id>/failed_writes |
||||
Date: August 2015 |
||||
Contact: Sergey Senozhatsky <sergey.senozhatsky@gmail.com> |
||||
Description: |
||||
The failed_writes file is read-only and specifies the number of |
||||
failed writes happened on this device. |
||||
Now accessible via zram<id>/io_stat node. |
||||
|
||||
What: /sys/block/zram<id>/notify_free |
||||
Date: August 2015 |
||||
Contact: Sergey Senozhatsky <sergey.senozhatsky@gmail.com> |
||||
Description: |
||||
The notify_free file is read-only. Depending on device usage |
||||
scenario it may account a) the number of pages freed because |
||||
of swap slot free notifications or b) the number of pages freed |
||||
because of REQ_DISCARD requests sent by bio. The former ones |
||||
are sent to a swap block device when a swap slot is freed, which |
||||
implies that this disk is being used as a swap disk. The latter |
||||
ones are sent by filesystem mounted with discard option, |
||||
whenever some data blocks are getting discarded. |
||||
Now accessible via zram<id>/io_stat node. |
||||
|
||||
What: /sys/block/zram<id>/zero_pages |
||||
Date: August 2015 |
||||
Contact: Sergey Senozhatsky <sergey.senozhatsky@gmail.com> |
||||
Description: |
||||
The zero_pages file is read-only and specifies number of zero |
||||
filled pages written to this disk. No memory is allocated for |
||||
such pages. |
||||
Now accessible via zram<id>/mm_stat node. |
||||
|
||||
What: /sys/block/zram<id>/orig_data_size |
||||
Date: August 2015 |
||||
Contact: Sergey Senozhatsky <sergey.senozhatsky@gmail.com> |
||||
Description: |
||||
The orig_data_size file is read-only and specifies uncompressed |
||||
size of data stored in this disk. This excludes zero-filled |
||||
pages (zero_pages) since no memory is allocated for them. |
||||
Unit: bytes |
||||
Now accessible via zram<id>/mm_stat node. |
||||
|
||||
What: /sys/block/zram<id>/compr_data_size |
||||
Date: August 2015 |
||||
Contact: Sergey Senozhatsky <sergey.senozhatsky@gmail.com> |
||||
Description: |
||||
The compr_data_size file is read-only and specifies compressed |
||||
size of data stored in this disk. So, compression ratio can be |
||||
calculated using orig_data_size and this statistic. |
||||
Unit: bytes |
||||
Now accessible via zram<id>/mm_stat node. |
||||
|
||||
What: /sys/block/zram<id>/mem_used_total |
||||
Date: August 2015 |
||||
Contact: Sergey Senozhatsky <sergey.senozhatsky@gmail.com> |
||||
Description: |
||||
The mem_used_total file is read-only and specifies the amount |
||||
of memory, including allocator fragmentation and metadata |
||||
overhead, allocated for this disk. So, allocator space |
||||
efficiency can be calculated using compr_data_size and this |
||||
statistic. |
||||
Unit: bytes |
||||
Now accessible via zram<id>/mm_stat node. |
||||
|
||||
What: /sys/block/zram<id>/mem_used_max |
||||
Date: August 2015 |
||||
Contact: Sergey Senozhatsky <sergey.senozhatsky@gmail.com> |
||||
Description: |
||||
The mem_used_max file is read/write and specifies the amount |
||||
of maximum memory zram have consumed to store compressed data. |
||||
For resetting the value, you should write "0". Otherwise, |
||||
you could see -EINVAL. |
||||
Unit: bytes |
||||
Downgraded to write-only node: so it's possible to set new |
||||
value only; its current value is stored in zram<id>/mm_stat |
||||
node. |
||||
|
||||
What: /sys/block/zram<id>/mem_limit |
||||
Date: August 2015 |
||||
Contact: Sergey Senozhatsky <sergey.senozhatsky@gmail.com> |
||||
Description: |
||||
The mem_limit file is read/write and specifies the maximum |
||||
amount of memory ZRAM can use to store the compressed data. |
||||
The limit could be changed in run time and "0" means disable |
||||
the limit. No limit is the initial state. Unit: bytes |
||||
Downgraded to write-only node: so it's possible to set new |
||||
value only; its current value is stored in zram<id>/mm_stat |
||||
node. |
@ -0,0 +1,70 @@ |
||||
zsmalloc |
||||
-------- |
||||
|
||||
This allocator is designed for use with zram. Thus, the allocator is |
||||
supposed to work well under low memory conditions. In particular, it |
||||
never attempts higher order page allocation which is very likely to |
||||
fail under memory pressure. On the other hand, if we just use single |
||||
(0-order) pages, it would suffer from very high fragmentation -- |
||||
any object of size PAGE_SIZE/2 or larger would occupy an entire page. |
||||
This was one of the major issues with its predecessor (xvmalloc). |
||||
|
||||
To overcome these issues, zsmalloc allocates a bunch of 0-order pages |
||||
and links them together using various 'struct page' fields. These linked |
||||
pages act as a single higher-order page i.e. an object can span 0-order |
||||
page boundaries. The code refers to these linked pages as a single entity |
||||
called zspage. |
||||
|
||||
For simplicity, zsmalloc can only allocate objects of size up to PAGE_SIZE |
||||
since this satisfies the requirements of all its current users (in the |
||||
worst case, page is incompressible and is thus stored "as-is" i.e. in |
||||
uncompressed form). For allocation requests larger than this size, failure |
||||
is returned (see zs_malloc). |
||||
|
||||
Additionally, zs_malloc() does not return a dereferenceable pointer. |
||||
Instead, it returns an opaque handle (unsigned long) which encodes actual |
||||
location of the allocated object. The reason for this indirection is that |
||||
zsmalloc does not keep zspages permanently mapped since that would cause |
||||
issues on 32-bit systems where the VA region for kernel space mappings |
||||
is very small. So, before using the allocating memory, the object has to |
||||
be mapped using zs_map_object() to get a usable pointer and subsequently |
||||
unmapped using zs_unmap_object(). |
||||
|
||||
stat |
||||
---- |
||||
|
||||
With CONFIG_ZSMALLOC_STAT, we could see zsmalloc internal information via |
||||
/sys/kernel/debug/zsmalloc/<user name>. Here is a sample of stat output: |
||||
|
||||
# cat /sys/kernel/debug/zsmalloc/zram0/classes |
||||
|
||||
class size almost_full almost_empty obj_allocated obj_used pages_used pages_per_zspage |
||||
.. |
||||
.. |
||||
9 176 0 1 186 129 8 4 |
||||
10 192 1 0 2880 2872 135 3 |
||||
11 208 0 1 819 795 42 2 |
||||
12 224 0 1 219 159 12 4 |
||||
.. |
||||
.. |
||||
|
||||
|
||||
class: index |
||||
size: object size zspage stores |
||||
almost_empty: the number of ZS_ALMOST_EMPTY zspages(see below) |
||||
almost_full: the number of ZS_ALMOST_FULL zspages(see below) |
||||
obj_allocated: the number of objects allocated |
||||
obj_used: the number of objects allocated to the user |
||||
pages_used: the number of pages allocated for the class |
||||
pages_per_zspage: the number of 0-order pages to make a zspage |
||||
|
||||
We assign a zspage to ZS_ALMOST_EMPTY fullness group when: |
||||
n <= N / f, where |
||||
n = number of allocated objects |
||||
N = total number of objects zspage can store |
||||
f = fullness_threshold_frac(ie, 4 at the moment) |
||||
|
||||
Similarly, we assign zspage to: |
||||
ZS_ALMOST_FULL when n > N / f |
||||
ZS_EMPTY when n == 0 |
||||
ZS_FULL when n == N |
@ -0,0 +1,66 @@ |
||||
#undef TRACE_SYSTEM |
||||
#define TRACE_SYSTEM cma |
||||
|
||||
#if !defined(_TRACE_CMA_H) || defined(TRACE_HEADER_MULTI_READ) |
||||
#define _TRACE_CMA_H |
||||
|
||||
#include <linux/types.h> |
||||
#include <linux/tracepoint.h> |
||||
|
||||
TRACE_EVENT(cma_alloc, |
||||
|
||||
TP_PROTO(unsigned long pfn, const struct page *page, |
||||
unsigned int count, unsigned int align), |
||||
|
||||
TP_ARGS(pfn, page, count, align), |
||||
|
||||
TP_STRUCT__entry( |
||||
__field(unsigned long, pfn) |
||||
__field(const struct page *, page) |
||||
__field(unsigned int, count) |
||||
__field(unsigned int, align) |
||||
), |
||||
|
||||
TP_fast_assign( |
||||
__entry->pfn = pfn; |
||||
__entry->page = page; |
||||
__entry->count = count; |
||||
__entry->align = align; |
||||
), |
||||
|
||||
TP_printk("pfn=%lx page=%p count=%u align=%u", |
||||
__entry->pfn, |
||||
__entry->page, |
||||
__entry->count, |
||||
__entry->align) |
||||
); |
||||
|
||||
TRACE_EVENT(cma_release, |
||||
|
||||
TP_PROTO(unsigned long pfn, const struct page *page, |
||||
unsigned int count), |
||||
|
||||
TP_ARGS(pfn, page, count), |
||||
|
||||
TP_STRUCT__entry( |
||||
__field(unsigned long, pfn) |
||||
__field(const struct page *, page) |
||||
__field(unsigned int, count) |
||||
), |
||||
|
||||
TP_fast_assign( |
||||
__entry->pfn = pfn; |
||||
__entry->page = page; |
||||
__entry->count = count; |
||||
), |
||||
|
||||
TP_printk("pfn=%lx page=%p count=%u", |
||||
__entry->pfn, |
||||
__entry->page, |
||||
__entry->count) |
||||
); |
||||
|
||||
#endif /* _TRACE_CMA_H */ |
||||
|
||||
/* This part must be outside protection */ |
||||
#include <trace/define_trace.h> |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue