Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Unverified Commit 73eb6631 authored by derfelot's avatar derfelot
Browse files

mm: Add z3fold special purpose allocator from Sony kernel

Taken from Sony 47.2.A.10.107 stock kernel
parent 9f0d14d1
Loading
Loading
Loading
Loading
+26 −0
Original line number Diff line number Diff line
z3fold
------

z3fold is a special purpose allocator for storing compressed pages.
It is designed to store up to three compressed pages per physical page.
It is a zbud derivative which allows for higher compression
ratio keeping the simplicity and determinism of its predecessor.

The main differences between z3fold and zbud are:
* unlike zbud, z3fold allows for up to PAGE_SIZE allocations
* z3fold can hold up to 3 compressed pages in its page
* z3fold doesn't export any API itself and is thus intended to be used
  via the zpool API.

To keep the determinism and simplicity, z3fold, just like zbud, always
stores an integral number of compressed pages per page, but it can store
up to 3 pages unlike zbud which can store at most 2. Therefore the
compression ratio goes to around 2.7x while zbud's one is around 1.7x.

Unlike zbud (but like zsmalloc for that matter) z3fold_alloc() does not
return a dereferenceable pointer. Instead, it returns an unsigned long
handle which encodes actual location of the allocated object.

Keeping effective compression ratio close to zsmalloc's, z3fold doesn't
depend on MMU enabled and provides more predictable reclaim behavior
which makes it a better fit for small and response-critical systems.
+4 −0
Original line number Diff line number Diff line
@@ -146,6 +146,9 @@ typedef void (dax_iodone_t)(struct buffer_head *bh_map, int uptodate);
/* File is stream-like */
#define FMODE_STREAM		((__force fmode_t)0x200000)

/* File hasn't page cache and can't be mmaped, for stackable filesystem */
#define FMODE_NONMAPPABLE       ((__force fmode_t)0x400000)

/* File was opened by fanotify and shouldn't generate fanotify events */
#define FMODE_NONOTIFY		((__force fmode_t)0x4000000)

@@ -1722,6 +1725,7 @@ struct file_operations {
#ifndef CONFIG_MMU
	unsigned (*mmap_capabilities)(struct file *);
#endif
	struct file* (*get_lower_file)(struct file *f);
};

struct inode_operations {
+12 −0
Original line number Diff line number Diff line
@@ -7,6 +7,11 @@
 * storage pool implementations.  Typically, this is used to
 * store compressed memory.
 */
/*
 * NOTE: This file has been modified by Sony Mobile Communications Inc.
 * Modifications are Copyright (c) 2015 Sony Mobile Communications Inc,
 * and licensed under the license of the file.
 */

#ifndef _ZPOOL_H_
#define _ZPOOL_H_
@@ -60,6 +65,9 @@ void zpool_unmap_handle(struct zpool *pool, unsigned long handle);

u64 zpool_get_total_size(struct zpool *pool);

unsigned long zpool_compact(struct zpool *pool);

unsigned long zpool_get_num_compacted(struct zpool *zpool);

/**
 * struct zpool_driver - driver implementation for zpool
@@ -101,6 +109,10 @@ struct zpool_driver {
	void (*unmap)(void *pool, unsigned long handle);

	u64 (*total_size)(void *pool);

	unsigned long (*compact)(void *pool);

	unsigned long (*get_num_compacted)(void *pool);
};

void zpool_register_driver(struct zpool_driver *driver);
+55 −0
Original line number Diff line number Diff line
/*
 * NOTE: This file has been modified by Sony Mobile Communications Inc.
 * Modifications are Copyright (c) 2017 Sony Mobile Communications Inc,
 * and licensed under the license of the file.
 */
#undef TRACE_SYSTEM
#define TRACE_SYSTEM kmem

@@ -214,6 +219,34 @@ TRACE_EVENT(mm_page_free_batched,
			__entry->cold)
);

TRACE_EVENT(mm_page_alloc_highorder,

	TP_PROTO(struct page *page, unsigned int order,
			gfp_t gfp_flags, int migratetype),

	TP_ARGS(page, order, gfp_flags, migratetype),

	TP_STRUCT__entry(__field(struct page *, page)
		__field(unsigned int, order)
		__field(gfp_t, gfp_flags)
		__field(int, migratetype)
	),

	TP_fast_assign(
		__entry->page		= page;
		__entry->order		= order;
		__entry->gfp_flags	= gfp_flags;
		__entry->migratetype	= migratetype;
	),

	TP_printk("page=%p pfn=%lu order=%d migratetype=%d gfp_flags=%s",
		__entry->page,
		page_to_pfn(__entry->page),
		__entry->order,
		__entry->migratetype,
		show_gfp_flags(__entry->gfp_flags))
);

TRACE_EVENT(mm_page_alloc,

	TP_PROTO(struct page *page, unsigned int order,
@@ -310,6 +343,28 @@ TRACE_EVENT_CONDITION(mm_page_pcpu_drain,
		__entry->order, __entry->migratetype)
);

TRACE_EVENT(mm_page_alloc_fail,

	TP_PROTO(int alloc_order, gfp_t gfp_mask),

	TP_ARGS(alloc_order, gfp_mask),

	TP_STRUCT__entry(
		__field(int, alloc_order)
		__field(gfp_t, gfp_mask)
	),

	TP_fast_assign(
		__entry->alloc_order		= alloc_order;
		__entry->gfp_mask		= gfp_mask;
	),

	TP_printk("alloc_order=%d pageblock_order=%d gfp_mask=%s",
		__entry->alloc_order,
		pageblock_order,
		show_gfp_flags(__entry->gfp_mask))
);

TRACE_EVENT(mm_page_alloc_extfrag,

	TP_PROTO(struct page *page,
+11 −1
Original line number Diff line number Diff line
@@ -557,7 +557,7 @@ config ZPOOL
	  zsmalloc.

config ZBUD
	tristate "Low density storage for compressed pages"
	tristate "Low (Up to 2x) density storage for compressed pages"
	default n
	help
	  A special purpose allocator for storing compressed pages.
@@ -566,6 +566,16 @@ config ZBUD
	  deterministic reclaim properties that make it preferable to a higher
	  density approach when reclaim will be used.

config Z3FOLD
	tristate "Up to 3x density storage for compressed pages"
	depends on ZPOOL
	default n
	help
	  A special purpose allocator for storing compressed pages.
	  It is designed to store up to three compressed pages per physical
	  page. It is a ZBUD derivative so the simplicity and determinism are
	  still there.

config ZSMALLOC
	tristate "Memory allocator for compressed pages"
	depends on MMU
Loading