porting moto_swap to kernel 5.15

Change-Id: I62f299f77298fc2dfea2b4e8f9e70ee899770120
Signed-off-by: huangzq2 <huangzq2@motorola.com>
Reviewed-on: https://gerrit.mot.com/2760974
SME-Granted: SME Approvals Granted
SLTApproved: Slta Waiver
Tested-by: Jira Key
Reviewed-by: Xiangpo Zhao <zhaoxp3@motorola.com>
Submit-Approved: Jira Key
This commit is contained in:
huangzq2 2023-10-09 07:34:17 +08:00 • committed by Zhangqing Huang
commit 154a44f565
12 changed files with 2689 additions and 17 deletions

View file

@ -1,17 +1,21 @@
DLKM_DIR := motorola/kernel/modules
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
KERNEL_CFLAGS += CONFIG_HYBRIDSWAP_ZRAM=y
#KERNEL_CFLAGS += CONFIG_HYBRIDSWAP_ZRAM_WRITEBACK=y
#KERNEL_CFLAGS += CONFIG_HYBRIDSWAP_ASYNC_COMPRESS=y
KERNEL_CFLAGS += CONFIG_HYBRIDSWAP=y
KERNEL_CFLAGS += CONFIG_HYBRIDSWAP_SWAPD=y
KERNEL_CFLAGS += CONFIG_HYBRIDSWAP_CORE=y
include $(CLEAR_VARS)
KBUILD_OPTIONS += CONFIG_HYBRIDSWAP_ZRAM=y
KBUILD_OPTIONS += CONFIG_HYBRIDSWAP=y
KBUILD_OPTIONS += CONFIG_HYBRIDSWAP_SWAPD=y
KBUILD_OPTIONS += CONFIG_HYBRIDSWAP_CORE=y
LOCAL_MODULE := moto_swap.ko
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT)
KBUILD_OPTIONS_GKI += GKI_OBJ_MODULE_DIR=gki
include $(DLKM_DIR)/AndroidKernelModule.mk

View file

@ -1,10 +1,15 @@
HAVE_KERNEL_5_4 = $(shell test -d $(ANDROID_BUILD_TOP)/kernel/msm-5.4 && echo 1)
HAVE_KERNEL_5_15 = $(shell test -d $(ANDROID_BUILD_TOP)/kernel_platform/gki/kernel/5.15 && echo 1)
ifeq ($(HAVE_KERNEL_5_4),1)
ZRAM_SRC = zram-5.4
EXTRA_CFLAGS += -DCONFIG_ZRAM_5_4
else ifeq ($(HAVE_KERNEL_5_15),1)
ZRAM_SRC = zram-5.15
EXTRA_CFLAGS += -DCONFIG_ZRAM_5_15
else
ZRAM_SRC = zram-5.10
EXTRA_CFLAGS += -DCONFIG_ZRAM_5_10
endif
# add -Wall to try to catch everything we can.

View file

@ -14,9 +14,16 @@
#ifdef CONFIG_ZRAM_5_4
#include "../zram-5.4/zram_drv.h"
#include "../zram-5.4/zram_drv_internal.h"
#define MEMCG_OEM_DATA(memcg) ((memcg)->android_oem_data1)
#elif defined CONFIG_ZRAM_5_15
#include "../zram-5.15/zram_drv.h"
#include "../zram-5.15/zram_drv_internal.h"
#define BIO_MAX_PAGES BIO_MAX_VECS
#define MEMCG_OEM_DATA(memcg) ((memcg)->android_oem_data1[0])
#else
#include "../zram-5.10/zram_drv.h"
#include "../zram-5.10/zram_drv_internal.h"
#define MEMCG_OEM_DATA(memcg) ((memcg)->android_oem_data1)
#endif
#include "hybridswap_internal.h"
#include "hybridswap.h"

View file

@ -20,9 +20,16 @@
#ifdef CONFIG_ZRAM_5_4
#include "../zram-5.4/zram_drv.h"
#include "../zram-5.4/zram_drv_internal.h"
#define MEMCG_OEM_DATA(memcg) ((memcg)->android_oem_data1)
#elif defined CONFIG_ZRAM_5_15
#include "../zram-5.15/zram_drv.h"
#include "../zram-5.15/zram_drv_internal.h"
#define BIO_MAX_PAGES BIO_MAX_VECS
#define MEMCG_OEM_DATA(memcg) ((memcg)->android_oem_data1[0])
#else
#include "../zram-5.10/zram_drv.h"
#include "../zram-5.10/zram_drv_internal.h"
#define MEMCG_OEM_DATA(memcg) ((memcg)->android_oem_data1)
#endif
#include "hybridswap_internal.h"
#include "hybridswap.h"
@ -1973,7 +1980,7 @@ static void __move_to_zram(struct zram *zram, u32 index, unsigned long handle,
static int move_to_zram(struct zram *zram, u32 index, struct io_eswapent *io_eswap)
{
unsigned long handle, eswpentry;
struct mem_cgroup *mcg = NULL;
// struct mem_cgroup *mcg = NULL;
int size, i;
u8 *dst = NULL;
@ -1990,7 +1997,7 @@ static int move_to_zram(struct zram *zram, u32 index, struct io_eswapent *io_esw
return -EINVAL;
}
mcg = io_eswap->mcg;
// mcg = io_eswap->mcg;
zram_slot_lock(zram, index);
eswpentry = zram_get_handle(zram, index);
if (zram_test_overwrite(zram, index, io_eswap->eswapid)) {
@ -4389,7 +4396,7 @@ ssize_t hybridswap_loop_device_store(struct device *dev,
memcpy(loop_device, buf, len);
loop_device[len] = '\0';
strstrip(loop_device);
(void) strstrip(loop_device);
zram = dev_to_zram(dev);
down_write(&zram->init_lock);
@ -5495,7 +5502,7 @@ void hybridswap_force_reclaim(struct mem_cgroup *mcg)
void mem_cgroup_id_remove_hook(void *data, struct mem_cgroup *memcg)
{
if (!memcg->android_oem_data1)
if (!MEMCG_OEM_DATA(memcg))
return;
hybridswap_mem_cgroup_deinit(memcg);

View file

@ -344,7 +344,12 @@ typedef struct mem_cgroup_hybridswap {
#endif
}memcg_hybs_t;
#ifdef CONFIG_ZRAM_5_15
#define MEMCGRP_ITEM_DATA(memcg) ((memcg_hybs_t *)(memcg)->android_oem_data1[0])
#else
#define MEMCGRP_ITEM_DATA(memcg) ((memcg_hybs_t *)(memcg)->android_oem_data1)
#endif
#define MEMCGRP_ITEM(memcg, item) (MEMCGRP_ITEM_DATA(memcg)->item)
extern void __put_memcg_cache(memcg_hybs_t *hybs);

View file

@ -7,6 +7,7 @@
#include <linux/slab.h>
#include <linux/cpu.h>
#include <linux/pagemap.h>
#include <trace/hooks/mm.h>
#include <trace/hooks/vmscan.h>
#include <linux/genhd.h>
@ -17,9 +18,29 @@
#ifdef CONFIG_ZRAM_5_4
#include "../zram-5.4/zram_drv.h"
#include "../zram-5.4/zram_drv_internal.h"
#define MEMCG_OEM_DATA(memcg) ((memcg)->android_oem_data1)
#elif defined CONFIG_ZRAM_5_15
#include "../zram-5.15/zram_drv.h"
#include "../zram-5.15/zram_drv_internal.h"
#define BIO_MAX_PAGES BIO_MAX_VECS
#define MEMCG_OEM_DATA(memcg) ((memcg)->android_oem_data1[0])
static unsigned long memcg_page_state_local(struct mem_cgroup *memcg, int idx)
{
long x = 0;
int cpu;
for_each_possible_cpu(cpu)
x += per_cpu(memcg->vmstats_percpu->state[idx], cpu);
#ifdef CONFIG_SMP
if (x < 0)
x = 0;
#endif
return x;
}
#else
#include "../zram-5.10/zram_drv.h"
#include "../zram-5.10/zram_drv_internal.h"
#define MEMCG_OEM_DATA(memcg) ((memcg)->android_oem_data1)
#endif
#include "hybridswap_internal.h"
#include "hybridswap.h"
@ -119,9 +140,17 @@ static inline void sum_hybridswap_vm_events(unsigned long *ret)
static inline void all_hybridswap_vm_events(unsigned long *ret)
{
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0)
get_online_cpus();
#else
cpus_read_lock();
#endif
sum_hybridswap_vm_events(ret);
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0)
put_online_cpus();
#else
cpus_read_unlock();
#endif
}
ssize_t hybridswap_vmstat_show(struct device *dev,
@ -191,7 +220,7 @@ memcg_hybs_t *hybridswap_cache_alloc(struct mem_cgroup *memcg, bool atomic)
u64 ret;
gfp_t flags = GFP_KERNEL;
if (memcg->android_oem_data1)
if (MEMCG_OEM_DATA(memcg))
BUG();
if (atomic)
@ -232,7 +261,7 @@ memcg_hybs_t *hybridswap_cache_alloc(struct mem_cgroup *memcg, bool atomic)
hybs->memcg = memcg;
refcount_set(&hybs->usage, 1);
ret = atomic64_cmpxchg((atomic64_t *)&memcg->android_oem_data1, 0, (u64)hybs);
ret = atomic64_cmpxchg((atomic64_t *)&MEMCG_OEM_DATA(memcg), 0, (u64)hybs);
if (ret != 0) {
#ifdef CONFIG_HYBRIDSWAP_ASYNC_COMPRESS
hybs->cache.dead = 1;
@ -286,7 +315,7 @@ static void tune_swappiness_hook(void *data, int *swappiness)
static void mem_cgroup_alloc_hook(void *data, struct mem_cgroup *memcg)
{
if (memcg->android_oem_data1)
if (MEMCG_OEM_DATA(memcg))
BUG();
hybridswap_cache_alloc(memcg, true);
@ -296,11 +325,11 @@ static void mem_cgroup_free_hook(void *data, struct mem_cgroup *memcg)
{
memcg_hybs_t *hybs;
if (!memcg->android_oem_data1)
if (!MEMCG_OEM_DATA(memcg))
return;
hybs = (memcg_hybs_t *)memcg->android_oem_data1;
memcg->android_oem_data1 = 0;
hybs = (memcg_hybs_t *)MEMCG_OEM_DATA(memcg);
MEMCG_OEM_DATA(memcg) = 0;
#ifdef CONFIG_HYBRIDSWAP_ASYNC_COMPRESS
clear_page_memcg(&hybs->cache);
#endif
@ -329,7 +358,7 @@ void memcg_app_grade_update(struct mem_cgroup *tarfetch)
static void mem_cgroup_css_online_hook(void *data,
struct cgroup_subsys_state *css, struct mem_cgroup *memcg)
{
if (memcg->android_oem_data1)
if (MEMCG_OEM_DATA(memcg))
memcg_app_grade_update(memcg);
css_get(css);
@ -340,7 +369,7 @@ static void mem_cgroup_css_offline_hook(void *data,
{
unsigned long flags;
if (memcg->android_oem_data1) {
if (MEMCG_OEM_DATA(memcg)) {
spin_lock_irqsave(&grade_list_lock, flags);
list_del_init(&MEMCGRP_ITEM(memcg, grade_node));
spin_unlock_irqrestore(&grade_list_lock, flags);
@ -457,6 +486,7 @@ unsigned long memcg_anon_pages(struct mem_cgroup *memcg)
return (lruvec_page_state(lruvec, NR_ACTIVE_ANON) +
lruvec_page_state(lruvec, NR_INACTIVE_ANON));
#endif
#else
return (memcg_page_state_local(memcg, NR_ACTIVE_ANON) +
memcg_page_state_local(memcg, NR_INACTIVE_ANON));

View file

@ -23,9 +23,16 @@
#ifdef CONFIG_ZRAM_5_4
#include "../zram-5.4/zram_drv.h"
#include "../zram-5.4/zram_drv_internal.h"
#define MEMCG_OEM_DATA(memcg) ((memcg)->android_oem_data1)
#elif defined CONFIG_ZRAM_5_15
#include "../zram-5.15/zram_drv.h"
#include "../zram-5.15/zram_drv_internal.h"
#define BIO_MAX_PAGES BIO_MAX_VECS
#define MEMCG_OEM_DATA(memcg) ((memcg)->android_oem_data1[0])
#else
#include "../zram-5.10/zram_drv.h"
#include "../zram-5.10/zram_drv_internal.h"
#define MEMCG_OEM_DATA(memcg) ((memcg)->android_oem_data1)
#endif
#include "hybridswap_internal.h"
@ -1817,7 +1824,7 @@ static int create_swapd_thread(struct zram *zram)
error_out:
for_each_node(nid) {
pgdat = NODE_DATA(node);
pgdat = NODE_DATA(nid);
if (!PGDAT_ITEM_DATA(pgdat))
continue;
@ -1841,7 +1848,7 @@ static void destroy_swapd_thread(void)
cpuhp_remove_state_nocalls(swapd_online);
for_each_node(nid) {
pgdat = NODE_DATA(node);
pgdat = NODE_DATA(nid);
if (!PGDAT_ITEM_DATA(pgdat))
continue;

View file

@ -0,0 +1,233 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (C) 2014 Sergey Senozhatsky.
*/
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/wait.h>
#include <linux/sched.h>
#include <linux/cpu.h>
#include <linux/crypto.h>
#include "zcomp.h"
static const char * const backends[] = {
#if IS_ENABLED(CONFIG_CRYPTO_LZO)
"lzo",
"lzo-rle",
#endif
#if IS_ENABLED(CONFIG_CRYPTO_LZ4)
"lz4",
#endif
#if IS_ENABLED(CONFIG_CRYPTO_LZ4HC)
"lz4hc",
#endif
#if IS_ENABLED(CONFIG_CRYPTO_842)
"842",
#endif
#if IS_ENABLED(CONFIG_CRYPTO_ZSTD)
"zstd",
#endif
};
static void zcomp_strm_free(struct zcomp_strm *zstrm)
{
if (!IS_ERR_OR_NULL(zstrm->tfm))
crypto_free_comp(zstrm->tfm);
free_pages((unsigned long)zstrm->buffer, 1);
zstrm->tfm = NULL;
zstrm->buffer = NULL;
}
/*
* Initialize zcomp_strm structure with ->tfm initialized by backend, and
* ->buffer. Return a negative value on error.
*/
static int zcomp_strm_init(struct zcomp_strm *zstrm, struct zcomp *comp)
{
zstrm->tfm = crypto_alloc_comp(comp->name, 0, 0);
/*
* allocate 2 pages. 1 for compressed data, plus 1 extra for the
* case when compressed size is larger than the original one
*/
zstrm->buffer = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, 1);
if (IS_ERR_OR_NULL(zstrm->tfm) || !zstrm->buffer) {
zcomp_strm_free(zstrm);
return -ENOMEM;
}
return 0;
}
bool zcomp_available_algorithm(const char *comp)
{
/*
* Crypto does not ignore a trailing new line symbol,
* so make sure you don't supply a string containing
* one.
* This also means that we permit zcomp initialisation
* with any compressing algorithm known to crypto api.
*/
return crypto_has_comp(comp, 0, 0) == 1;
}
/* show available compressors */
ssize_t zcomp_available_show(const char *comp, char *buf)
{
bool known_algorithm = false;
ssize_t sz = 0;
int i;
for (i = 0; i < ARRAY_SIZE(backends); i++) {
if (!strcmp(comp, backends[i])) {
known_algorithm = true;
sz += scnprintf(buf + sz, PAGE_SIZE - sz - 2,
"[%s] ", backends[i]);
} else {
sz += scnprintf(buf + sz, PAGE_SIZE - sz - 2,
"%s ", backends[i]);
}
}
/*
* Out-of-tree module known to crypto api or a missing
* entry in `backends'.
*/
if (!known_algorithm && crypto_has_comp(comp, 0, 0) == 1)
sz += scnprintf(buf + sz, PAGE_SIZE - sz - 2,
"[%s] ", comp);
sz += scnprintf(buf + sz, PAGE_SIZE - sz, "\n");
return sz;
}
struct zcomp_strm *zcomp_stream_get(struct zcomp *comp)
{
local_lock(&comp->stream->lock);
return this_cpu_ptr(comp->stream);
}
void zcomp_stream_put(struct zcomp *comp)
{
local_unlock(&comp->stream->lock);
}
int zcomp_compress(struct zcomp_strm *zstrm,
const void *src, unsigned int *dst_len)
{
/*
* Our dst memory (zstrm->buffer) is always `2 * PAGE_SIZE' sized
* because sometimes we can endup having a bigger compressed data
* due to various reasons: for example compression algorithms tend
* to add some padding to the compressed buffer. Speaking of padding,
* comp algorithm `842' pads the compressed length to multiple of 8
* and returns -ENOSP when the dst memory is not big enough, which
* is not something that ZRAM wants to see. We can handle the
* `compressed_size > PAGE_SIZE' case easily in ZRAM, but when we
* receive -ERRNO from the compressing backend we can't help it
* anymore. To make `842' happy we need to tell the exact size of
* the dst buffer, zram_drv will take care of the fact that
* compressed buffer is too big.
*/
*dst_len = PAGE_SIZE * 2;
return crypto_comp_compress(zstrm->tfm,
src, PAGE_SIZE,
zstrm->buffer, dst_len);
}
int zcomp_decompress(struct zcomp_strm *zstrm,
const void *src, unsigned int src_len, void *dst)
{
unsigned int dst_len = PAGE_SIZE;
return crypto_comp_decompress(zstrm->tfm,
src, src_len,
dst, &dst_len);
}
int zcomp_cpu_up_prepare(unsigned int cpu, struct hlist_node *node)
{
struct zcomp *comp = hlist_entry(node, struct zcomp, node);
struct zcomp_strm *zstrm;
int ret;
zstrm = per_cpu_ptr(comp->stream, cpu);
local_lock_init(&zstrm->lock);
ret = zcomp_strm_init(zstrm, comp);
if (ret)
pr_err("Can't allocate a compression stream\n");
return ret;
}
int zcomp_cpu_dead(unsigned int cpu, struct hlist_node *node)
{
struct zcomp *comp = hlist_entry(node, struct zcomp, node);
struct zcomp_strm *zstrm;
zstrm = per_cpu_ptr(comp->stream, cpu);
zcomp_strm_free(zstrm);
return 0;
}
static int zcomp_init(struct zcomp *comp)
{
int ret;
comp->stream = alloc_percpu(struct zcomp_strm);
if (!comp->stream)
return -ENOMEM;
ret = cpuhp_state_add_instance(CPUHP_ZCOMP_PREPARE, &comp->node);
if (ret < 0)
goto cleanup;
return 0;
cleanup:
free_percpu(comp->stream);
return ret;
}
void zcomp_destroy(struct zcomp *comp)
{
cpuhp_state_remove_instance(CPUHP_ZCOMP_PREPARE, &comp->node);
free_percpu(comp->stream);
kfree(comp);
}
/*
* search available compressors for requested algorithm.
* allocate new zcomp and initialize it. return compressing
* backend pointer or ERR_PTR if things went bad. ERR_PTR(-EINVAL)
* if requested algorithm is not supported, ERR_PTR(-ENOMEM) in
* case of allocation error, or any other error potentially
* returned by zcomp_init().
*/
struct zcomp *zcomp_create(const char *compress)
{
struct zcomp *comp;
int error;
/*
* Crypto API will execute /sbin/modprobe if the compression module
* is not loaded yet. We must do it here, otherwise we are about to
* call /sbin/modprobe under CPU hot-plug lock.
*/
if (!zcomp_available_algorithm(compress))
return ERR_PTR(-EINVAL);
comp = kzalloc(sizeof(struct zcomp), GFP_KERNEL);
if (!comp)
return ERR_PTR(-ENOMEM);
comp->name = compress;
error = zcomp_init(comp);
if (error) {
kfree(comp);
return ERR_PTR(error);
}
return comp;
}

View file

@ -0,0 +1,43 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright (C) 2014 Sergey Senozhatsky.
*/
#ifndef _ZCOMP_H_
#define _ZCOMP_H_
#include <linux/local_lock.h>
struct zcomp_strm {
/* The members ->buffer and ->tfm are protected by ->lock. */
local_lock_t lock;
/* compression/decompression buffer */
void *buffer;
struct crypto_comp *tfm;
};
/* dynamic per-device compression frontend */
struct zcomp {
struct zcomp_strm __percpu *stream;
const char *name;
struct hlist_node node;
};
int zcomp_cpu_up_prepare(unsigned int cpu, struct hlist_node *node);
int zcomp_cpu_dead(unsigned int cpu, struct hlist_node *node);
ssize_t zcomp_available_show(const char *comp, char *buf);
bool zcomp_available_algorithm(const char *comp);
struct zcomp *zcomp_create(const char *comp);
void zcomp_destroy(struct zcomp *comp);
struct zcomp_strm *zcomp_stream_get(struct zcomp *comp);
void zcomp_stream_put(struct zcomp *comp);
int zcomp_compress(struct zcomp_strm *zstrm,
const void *src, unsigned int *dst_len);
int zcomp_decompress(struct zcomp_strm *zstrm,
const void *src, unsigned int src_len, void *dst);
bool zcomp_set_max_streams(struct zcomp *comp, int num_strm);
#endif /* _ZCOMP_H_ */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,144 @@
/*
* Compressed RAM block device
*
* Copyright (C) 2008, 2009, 2010 Nitin Gupta
* 2012, 2013 Minchan Kim
*
* This code is released using a dual license strategy: BSD/GPL
* You can choose the licence that better fits your requirements.
*
* Released under the terms of 3-clause BSD License
* Released under the terms of GNU General Public License Version 2.0
*
*/
#ifndef _ZRAM_DRV_H_
#define _ZRAM_DRV_H_
#include <linux/rwsem.h>
#include <linux/zsmalloc.h>
#include <linux/crypto.h>
#include "zcomp.h"
#define SECTORS_PER_PAGE_SHIFT (PAGE_SHIFT - SECTOR_SHIFT)
#define SECTORS_PER_PAGE (1 << SECTORS_PER_PAGE_SHIFT)
#define ZRAM_LOGICAL_BLOCK_SHIFT 12
#define ZRAM_LOGICAL_BLOCK_SIZE (1 << ZRAM_LOGICAL_BLOCK_SHIFT)
#define ZRAM_SECTOR_PER_LOGICAL_BLOCK \
(1 << (ZRAM_LOGICAL_BLOCK_SHIFT - SECTOR_SHIFT))
/*
* The lower ZRAM_FLAG_SHIFT bits of table.flags is for
* object size (excluding header), the higher bits is for
* zram_pageflags.
*
* zram is mainly used for memory efficiency so we want to keep memory
* footprint small so we can squeeze size and flags into a field.
* The lower ZRAM_FLAG_SHIFT bits is for object size (excluding header),
* the higher bits is for zram_pageflags.
*/
#define ZRAM_FLAG_SHIFT 24
/* Flags for zram pages (table[page_no].flags) */
enum zram_pageflags {
/* zram slot is locked */
ZRAM_LOCK = ZRAM_FLAG_SHIFT,
ZRAM_SAME, /* Page consists the same element */
ZRAM_WB, /* page is stored on backing_device */
ZRAM_UNDER_WB, /* page is under writeback */
ZRAM_HUGE, /* Incompressible page */
ZRAM_IDLE, /* not accessed page since last idle marking */
#ifdef CONFIG_HYBRIDSWAP_CORE
ZRAM_BATCHING_OUT,
ZRAM_FROM_HYBRIDSWAP,
ZRAM_MCGID_CLEAR,
ZRAM_IN_BD, /* zram stored in back device */
#endif
__NR_ZRAM_PAGEFLAGS,
};
/*-- Data structures */
/* Allocated for each disk page */
struct zram_table_entry {
union {
unsigned long handle;
unsigned long element;
};
unsigned long flags;
#ifdef CONFIG_HYBRIDSWAP_ZRAM_MEMORY_TRACKING
ktime_t ac_time;
#endif
};
struct zram_stats {
atomic64_t compr_data_size; /* compressed size of pages stored */
atomic64_t num_reads; /* failed + successful */
atomic64_t num_writes; /* --do-- */
atomic64_t failed_reads; /* can happen when memory is too low */
atomic64_t failed_writes; /* can happen when memory is too low */
atomic64_t invalid_io; /* non-page-aligned I/O requests */
atomic64_t notify_free; /* no. of swap slot free notifications */
atomic64_t same_pages; /* no. of same element filled pages */
atomic64_t huge_pages; /* no. of huge pages */
atomic64_t huge_pages_since; /* no. of huge pages since zram set up */
atomic64_t pages_stored; /* no. of pages currently stored */
atomic_long_t max_used_pages; /* no. of maximum pages stored */
atomic64_t writestall; /* no. of write slow paths */
atomic64_t miss_free; /* no. of missed free */
#ifdef CONFIG_HYBRIDSWAP_ZRAM_WRITEBACK
atomic64_t bd_count; /* no. of pages in backing device */
atomic64_t bd_reads; /* no. of reads from backing device */
atomic64_t bd_writes; /* no. of writes from backing device */
#endif
};
struct zram {
struct zram_table_entry *table;
struct zs_pool *mem_pool;
struct zcomp *comp;
struct gendisk *disk;
/* Prevent concurrent execution of device init */
struct rw_semaphore init_lock;
/*
* the number of pages zram can consume for storing compressed data
*/
unsigned long limit_pages;
struct zram_stats stats;
/*
* This is the limit on amount of *uncompressed* worth of data
* we can store in a disk.
*/
u64 disksize; /* bytes */
char compressor[CRYPTO_MAX_ALG_NAME];
/*
* zram is claimed so open request will be failed
*/
bool claim; /* Protected by disk->open_mutex */
struct file *backing_dev;
#ifdef CONFIG_HYBRIDSWAP_ZRAM_WRITEBACK
spinlock_t wb_limit_lock;
bool wb_limit_enable;
u64 bd_wb_limit;
struct block_device *bdev;
unsigned long *bitmap;
unsigned long nr_pages;
#endif
#ifdef CONFIG_HYBRIDSWAP_ZRAM_MEMORY_TRACKING
struct dentry *debugfs_dir;
#endif
#if (defined CONFIG_HYBRIDSWAP_ZRAM_WRITEBACK) || (defined CONFIG_HYBRIDSWAP_CORE)
struct block_device *bdev;
unsigned int old_block_size;
unsigned long nr_pages;
unsigned long increase_nr_pages;
#endif
#ifdef CONFIG_HYBRIDSWAP_CORE
struct hyb_info *infos;
#endif
};
#endif

View file

@ -0,0 +1,35 @@
#ifndef _ZRAM_DRV_INTERNAL_H_
#define _ZRAM_DRV_INTERNAL_H_
#ifdef BIT
#undef BIT
#define BIT(nr) (1lu << (nr))
#endif
#define zram_slot_lock(zram, index) (bit_spin_lock(ZRAM_LOCK, &zram->table[index].flags))
#define zram_slot_unlock(zram, index) (bit_spin_unlock(ZRAM_LOCK, &zram->table[index].flags))
#define init_done(zram) (zram->disksize)
#define dev_to_zram(dev) ((struct zram *)dev_to_disk(dev)->private_data)
#define zram_get_handle(zram, index) (zram->table[index].handle)
#define zram_set_handle(zram, index, handle_val) (zram->table[index].handle = handle_val)
#define zram_test_flag(zram, index, flag) (zram->table[index].flags & BIT(flag))
#define zram_set_flag(zram, index, flag) (zram->table[index].flags |= BIT(flag))
#define zram_clear_flag(zram, index, flag) (zram->table[index].flags &= ~BIT(flag))
#define zram_set_element(zram, index, element) (zram->table[index].element = element)
#define zram_get_obj_size(zram, index) (zram->table[index].flags & (BIT(ZRAM_FLAG_SHIFT) - 1))
#define zram_set_obj_size(zram, index, size) do {\
unsigned long flags = zram->table[index].flags >> ZRAM_FLAG_SHIFT; \
zram->table[index].flags = (flags << ZRAM_FLAG_SHIFT) | size; \
} while(0)
#endif