/*
 * Copyright (C) 2013-2016 ARM Limited. All rights reserved.
 * 
 * This program is free software and is provided to you under the terms of the GNU General Public License version 2
 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
 * 
 * A copy of the licence is included with the program, and can also be obtained from Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

#include <linux/list.h>
#include <linux/mm.h>
#include <linux/mm_types.h>
#include <linux/fs.h>
#include <linux/dma-mapping.h>
#include <linux/slab.h>
#include <linux/version.h>
#include <linux/sched.h>
#include <linux/idr.h>
#include <linux/platform_device.h>
#include <linux/workqueue.h>
#include <linux/shmem_fs.h>
#include <linux/file.h>
#include <linux/swap.h>
#include <linux/pagemap.h>
#include "mali_osk.h"
#include "mali_osk_mali.h"
#include "mali_memory.h"
#include "mali_memory_manager.h"
#include "mali_memory_virtual.h"
#include "mali_memory_cow.h"
#include "mali_ukk.h"
#include "mali_kernel_utilization.h"
#include "mali_memory_swap_alloc.h"


static struct _mali_osk_bitmap idx_mgr;
static struct file *global_swap_file;
static struct address_space *global_swap_space;
static _mali_osk_wq_work_t *mali_mem_swap_out_workq = NULL;
static u32 mem_backend_swapped_pool_size;
#ifdef MALI_MEM_SWAP_TRACKING
static u32 mem_backend_swapped_unlock_size;
#endif
/* Lock order: mem_backend_swapped_pool_lock  > each memory backend's mutex lock.
 * This lock used to protect mem_backend_swapped_pool_size and mem_backend_swapped_pool. */
static struct mutex mem_backend_swapped_pool_lock;
static struct list_head mem_backend_swapped_pool;

extern struct mali_mem_os_allocator mali_mem_os_allocator;

#define MALI_SWAP_LOW_MEM_DEFAULT_VALUE (60*1024*1024)
#define MALI_SWAP_INVALIDATE_MALI_ADDRESS (0)               /* Used to mark the given memory cookie is invalidate. */
#define MALI_SWAP_GLOBAL_SWAP_FILE_SIZE (0xFFFFFFFF)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0)
#define MALI_SWAP_GLOBAL_SWAP_FILE_INDEX ((MALI_SWAP_GLOBAL_SWAP_FILE_SIZE) >> PAGE_SHIFT)
#else
#define MALI_SWAP_GLOBAL_SWAP_FILE_INDEX ((MALI_SWAP_GLOBAL_SWAP_FILE_SIZE) >> PAGE_CACHE_SHIFT)
#endif
#define MALI_SWAP_GLOBAL_SWAP_FILE_INDEX_RESERVE (1 << 15) /* Reserved for CoW nonlinear swap backend memory, the space size is 128MB. */

unsigned int mali_mem_swap_out_threshold_value = MALI_SWAP_LOW_MEM_DEFAULT_VALUE;

/**
 * We have two situations to do shrinking things, one is we met low GPU utilization which shows GPU needn't touch too
 * swappable backends in short time, and the other one is we add new swappable backends, the total pool size exceed
 * the threshold value of the swapped pool size.
 */
typedef enum {
	MALI_MEM_SWAP_SHRINK_WITH_LOW_UTILIZATION = 100,
	MALI_MEM_SWAP_SHRINK_FOR_ADDING_NEW_BACKENDS = 257,
} _mali_mem_swap_pool_shrink_type_t;

static void mali_mem_swap_swapped_bkend_pool_check_for_low_utilization(void *arg);

_mali_osk_errcode_t mali_mem_swap_init(void)
{
	gfp_t flags = __GFP_NORETRY | __GFP_NOWARN;

	if (_MALI_OSK_ERR_OK != _mali_osk_bitmap_init(&idx_mgr, MALI_SWAP_GLOBAL_SWAP_FILE_INDEX, MALI_SWAP_GLOBAL_SWAP_FILE_INDEX_RESERVE)) {
		return _MALI_OSK_ERR_NOMEM;
	}

	global_swap_file = shmem_file_setup("mali_swap", MALI_SWAP_GLOBAL_SWAP_FILE_SIZE, VM_NORESERVE);
	if (IS_ERR(global_swap_file)) {
		_mali_osk_bitmap_term(&idx_mgr);
		return _MALI_OSK_ERR_NOMEM;
	}

	global_swap_space = global_swap_file->f_path.dentry->d_inode->i_mapping;

	mali_mem_swap_out_workq = _mali_osk_wq_create_work(mali_mem_swap_swapped_bkend_pool_check_for_low_utilization, NULL);
	if (NULL == mali_mem_swap_out_workq) {
		_mali_osk_bitmap_term(&idx_mgr);
		fput(global_swap_file);
		return _MALI_OSK_ERR_NOMEM;
	}

#if defined(CONFIG_ARM) && !defined(CONFIG_ARM_LPAE)
	flags |= GFP_HIGHUSER;
#else
#ifdef CONFIG_ZONE_DMA32
	flags |= GFP_DMA32;
#else
#ifdef CONFIG_ZONE_DMA
	flags |= GFP_DMA;
#else
	/* arm64 utgard only work on < 4G, but the kernel
	 * didn't provide method to allocte memory < 4G
	 */
	MALI_DEBUG_ASSERT(0);
#endif
#endif
#endif

	/* When we use shmem_read_mapping_page to allocate/swap-in, it will
	 * use these flags to allocate new page if need.*/
	mapping_set_gfp_mask(global_swap_space, flags);

	mem_backend_swapped_pool_size = 0;
#ifdef MALI_MEM_SWAP_TRACKING
	mem_backend_swapped_unlock_size = 0;
#endif
	mutex_init(&mem_backend_swapped_pool_lock);
	INIT_LIST_HEAD(&mem_backend_swapped_pool);

	MALI_DEBUG_PRINT(2, ("Mali SWAP: Swap out threshold vaule is %uM\n", mali_mem_swap_out_threshold_value >> 20));

	return _MALI_OSK_ERR_OK;
}

void mali_mem_swap_term(void)
{
	_mali_osk_bitmap_term(&idx_mgr);

	fput(global_swap_file);

	_mali_osk_wq_delete_work(mali_mem_swap_out_workq);

	MALI_DEBUG_ASSERT(list_empty(&mem_backend_swapped_pool));
	MALI_DEBUG_ASSERT(0 == mem_backend_swapped_pool_size);

	return;
}

struct file *mali_mem_swap_get_global_swap_file(void)
{
	return  global_swap_file;
}

/* Judge if swappable backend in swapped pool. */
static mali_bool mali_memory_swap_backend_in_swapped_pool(mali_mem_backend *mem_bkend)
{
	MALI_DEBUG_ASSERT_POINTER(mem_bkend);

	return !list_empty(&mem_bkend->list);
}

void mali_memory_swap_list_backend_delete(mali_mem_backend *mem_bkend)
{
	MALI_DEBUG_ASSERT_POINTER(mem_bkend);

	mutex_lock(&mem_backend_swapped_pool_lock);
	mutex_lock(&mem_bkend->mutex);

	if (MALI_FALSE == mali_memory_swap_backend_in_swapped_pool(mem_bkend)) {
		mutex_unlock(&mem_bkend->mutex);
		mutex_unlock(&mem_backend_swapped_pool_lock);
		return;
	}

	MALI_DEBUG_ASSERT(!list_empty(&mem_bkend->list));

	list_del_init(&mem_bkend->list);

	mutex_unlock(&mem_bkend->mutex);

	mem_backend_swapped_pool_size -= mem_bkend->size;

	mutex_unlock(&mem_backend_swapped_pool_lock);
}

static void mali_mem_swap_out_page_node(mali_page_node *page_node)
{
	MALI_DEBUG_ASSERT(page_node);

	dma_unmap_page(&mali_platform_device->dev, page_node->swap_it->dma_addr,
		       _MALI_OSK_MALI_PAGE_SIZE, DMA_TO_DEVICE);
	set_page_dirty(page_node->swap_it->page);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0)
	put_page(page_node->swap_it->page);
#else
	page_cache_release(page_node->swap_it->page);
#endif
}

void mali_mem_swap_unlock_single_mem_backend(mali_mem_backend *mem_bkend)
{
	mali_page_node *m_page;

	MALI_DEBUG_ASSERT(1 == mutex_is_locked(&mem_bkend->mutex));

	if (MALI_MEM_BACKEND_FLAG_UNSWAPPED_IN == (mem_bkend->flags & MALI_MEM_BACKEND_FLAG_UNSWAPPED_IN)) {
		return;
	}

	mem_bkend->flags |= MALI_MEM_BACKEND_FLAG_UNSWAPPED_IN;

	list_for_each_entry(m_page, &mem_bkend->swap_mem.pages, list) {
		mali_mem_swap_out_page_node(m_page);
	}

	return;
}

static void mali_mem_swap_unlock_partial_locked_mem_backend(mali_mem_backend *mem_bkend, mali_page_node *page_node)
{
	mali_page_node *m_page;

	MALI_DEBUG_ASSERT(1 == mutex_is_locked(&mem_bkend->mutex));

	list_for_each_entry(m_page, &mem_bkend->swap_mem.pages, list) {
		if (m_page == page_node) {
			break;
		}
		mali_mem_swap_out_page_node(m_page);
	}
}

static void mali_mem_swap_swapped_bkend_pool_shrink(_mali_mem_swap_pool_shrink_type_t shrink_type)
{
	mali_mem_backend *bkend, *tmp_bkend;
	long system_free_size;
	u32 last_gpu_utilization, gpu_utilization_threshold_value, temp_swap_out_threshold_value;

	MALI_DEBUG_ASSERT(1 == mutex_is_locked(&mem_backend_swapped_pool_lock));

	if (MALI_MEM_SWAP_SHRINK_WITH_LOW_UTILIZATION == shrink_type) {
		/**
		 * When we met that system memory is very low and Mali locked swappable memory size is less than
		 * threshold value, and at the same time, GPU load is very low and don't need high performance,
		 * at this condition, we can unlock more swap memory backend from swapped backends pool.
		 */
		gpu_utilization_threshold_value = MALI_MEM_SWAP_SHRINK_WITH_LOW_UTILIZATION;
		temp_swap_out_threshold_value = (mali_mem_swap_out_threshold_value >> 2);
	} else {
		/* When we add swappable memory backends to swapped pool, we need to think that we couldn't
		* hold too much swappable backends in Mali driver, and also we need considering performance.
		* So there is a balance for swapping out memory backend, we should follow the following conditions:
		* 1. Total memory size in global mem backend swapped pool is more than the defined threshold value.
		* 2. System level free memory size is less than the defined threshold value.
		* 3. Please note that GPU utilization problem isn't considered in this condition.
		*/
		gpu_utilization_threshold_value = MALI_MEM_SWAP_SHRINK_FOR_ADDING_NEW_BACKENDS;
		temp_swap_out_threshold_value = mali_mem_swap_out_threshold_value;
	}

	/* Get system free pages number. */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)
	system_free_size = global_zone_page_state(NR_FREE_PAGES) * PAGE_SIZE;
#else
	system_free_size = global_page_state(NR_FREE_PAGES) * PAGE_SIZE;
#endif
	last_gpu_utilization = _mali_ukk_utilization_gp_pp();

	if ((last_gpu_utilization < gpu_utilization_threshold_value)
	    && (system_free_size < mali_mem_swap_out_threshold_value)
	    && (mem_backend_swapped_pool_size > temp_swap_out_threshold_value)) {
		list_for_each_entry_safe(bkend, tmp_bkend, &mem_backend_swapped_pool, list) {
			if (mem_backend_swapped_pool_size <= temp_swap_out_threshold_value) {
				break;
			}

			mutex_lock(&bkend->mutex);

			/* check if backend is in use. */
			if (0 < bkend->using_count) {
				mutex_unlock(&bkend->mutex);
				continue;
			}

			mali_mem_swap_unlock_single_mem_backend(bkend);
			list_del_init(&bkend->list);
			mem_backend_swapped_pool_size -= bkend->size;
#ifdef MALI_MEM_SWAP_TRACKING
			mem_backend_swapped_unlock_size += bkend->size;
#endif
			mutex_unlock(&bkend->mutex);
		}
	}

	return;
}

static void mali_mem_swap_swapped_bkend_pool_check_for_low_utilization(void *arg)
{
	MALI_IGNORE(arg);

	mutex_lock(&mem_backend_swapped_pool_lock);

	mali_mem_swap_swapped_bkend_pool_shrink(MALI_MEM_SWAP_SHRINK_WITH_LOW_UTILIZATION);

	mutex_unlock(&mem_backend_swapped_pool_lock);
}

/**
 * After PP job finished, we add all of swappable memory backend used by this PP
 * job to the tail of the global swapped pool, and if the total size of swappable memory is more than threshold
 * value, we also need to shrink the swapped pool start from the head of the list.
 */
void mali_memory_swap_list_backend_add(mali_mem_backend *mem_bkend)
{
	mutex_lock(&mem_backend_swapped_pool_lock);
	mutex_lock(&mem_bkend->mutex);

	if (mali_memory_swap_backend_in_swapped_pool(mem_bkend)) {
		MALI_DEBUG_ASSERT(!list_empty(&mem_bkend->list));

		list_del_init(&mem_bkend->list);
		list_add_tail(&mem_bkend->list, &mem_backend_swapped_pool);
		mutex_unlock(&mem_bkend->mutex);
		mutex_unlock(&mem_backend_swapped_pool_lock);
		return;
	}

	list_add_tail(&mem_bkend->list, &mem_backend_swapped_pool);

	mutex_unlock(&mem_bkend->mutex);
	mem_backend_swapped_pool_size += mem_bkend->size;

	mali_mem_swap_swapped_bkend_pool_shrink(MALI_MEM_SWAP_SHRINK_FOR_ADDING_NEW_BACKENDS);

	mutex_unlock(&mem_backend_swapped_pool_lock);
	return;
}


u32 mali_mem_swap_idx_alloc(void)
{
	return _mali_osk_bitmap_alloc(&idx_mgr);
}

void mali_mem_swap_idx_free(u32 idx)
{
	_mali_osk_bitmap_free(&idx_mgr, idx);
}

static u32 mali_mem_swap_idx_range_alloc(u32 count)
{
	u32 index;

	index = _mali_osk_bitmap_alloc_range(&idx_mgr, count);

	return index;
}

static void mali_mem_swap_idx_range_free(u32 idx, int num)
{
	_mali_osk_bitmap_free_range(&idx_mgr, idx, num);
}

struct mali_swap_item *mali_mem_swap_alloc_swap_item(void)
{
	mali_swap_item *swap_item;

	swap_item = kzalloc(sizeof(mali_swap_item), GFP_KERNEL);

	if (NULL == swap_item) {
		return NULL;
	}

	atomic_set(&swap_item->ref_count, 1);
	swap_item->page = NULL;
	atomic_add(1, &mali_mem_os_allocator.allocated_pages);

	return swap_item;
}

void mali_mem_swap_free_swap_item(mali_swap_item *swap_item)
{
	struct inode *file_node;
	long long start, end;

	/* If this swap item is shared, we just reduce the reference counter. */
	if (0 == atomic_dec_return(&swap_item->ref_count)) {
		file_node = global_swap_file->f_path.dentry->d_inode;
		start = swap_item->idx;
		start = start << 12;
		end = start + PAGE_SIZE;

		shmem_truncate_range(file_node, start, (end - 1));

		mali_mem_swap_idx_free(swap_item->idx);

		atomic_sub(1, &mali_mem_os_allocator.allocated_pages);

		kfree(swap_item);
	}
}

/* Used to allocate new swap item for new memory allocation and cow page for write. */
struct mali_page_node *_mali_mem_swap_page_node_allocate(void)
{
	struct mali_page_node *m_page;

	m_page = _mali_page_node_allocate(MALI_PAGE_NODE_SWAP);

	if (NULL == m_page) {
		return NULL;
	}

	m_page->swap_it = mali_mem_swap_alloc_swap_item();

	if (NULL == m_page->swap_it) {
		kfree(m_page);
		return NULL;
	}

	return m_page;
}

_mali_osk_errcode_t _mali_mem_swap_put_page_node(struct mali_page_node *m_page)
{

	mali_mem_swap_free_swap_item(m_page->swap_it);

	return _MALI_OSK_ERR_OK;
}

void _mali_mem_swap_page_node_free(struct mali_page_node *m_page)
{
	_mali_mem_swap_put_page_node(m_page);

	kfree(m_page);

	return;
}

u32 mali_mem_swap_free(mali_mem_swap *swap_mem)
{
	struct mali_page_node *m_page, *m_tmp;
	u32 free_pages_nr = 0;

	MALI_DEBUG_ASSERT_POINTER(swap_mem);

	list_for_each_entry_safe(m_page, m_tmp, &swap_mem->pages, list) {
		MALI_DEBUG_ASSERT(m_page->type == MALI_PAGE_NODE_SWAP);

		/* free the page node and release the swap item, if the ref count is 1,
		 * then need also free the swap item. */
		list_del(&m_page->list);
		if (1 == _mali_page_node_get_ref_count(m_page)) {
			free_pages_nr++;
		}

		_mali_mem_swap_page_node_free(m_page);
	}

	return free_pages_nr;
}

static u32 mali_mem_swap_cow_free(mali_mem_cow *cow_mem)
{
	struct mali_page_node *m_page, *m_tmp;
	u32 free_pages_nr = 0;

	MALI_DEBUG_ASSERT_POINTER(cow_mem);

	list_for_each_entry_safe(m_page, m_tmp, &cow_mem->pages, list) {
		MALI_DEBUG_ASSERT(m_page->type == MALI_PAGE_NODE_SWAP);

		/* free the page node and release the swap item, if the ref count is 1,
		 * then need also free the swap item. */
		list_del(&m_page->list);
		if (1 == _mali_page_node_get_ref_count(m_page)) {
			free_pages_nr++;
		}

		_mali_mem_swap_page_node_free(m_page);
	}

	return free_pages_nr;
}

u32 mali_mem_swap_release(mali_mem_backend *mem_bkend, mali_bool is_mali_mapped)
{
	mali_mem_allocation *alloc;
	u32 free_pages_nr = 0;

	MALI_DEBUG_ASSERT_POINTER(mem_bkend);
	alloc = mem_bkend->mali_allocation;
	MALI_DEBUG_ASSERT_POINTER(alloc);

	if (is_mali_mapped) {
		mali_mem_swap_mali_unmap(alloc);
	}

	mali_memory_swap_list_backend_delete(mem_bkend);

	mutex_lock(&mem_bkend->mutex);
	/* To make sure the given memory backend was unlocked from Mali side,
	 * and then free this memory block. */
	mali_mem_swap_unlock_single_mem_backend(mem_bkend);
	mutex_unlock(&mem_bkend->mutex);

	if (MALI_MEM_SWAP == mem_bkend->type) {
		free_pages_nr = mali_mem_swap_free(&mem_bkend->swap_mem);
	} else {
		free_pages_nr = mali_mem_swap_cow_free(&mem_bkend->cow_mem);
	}

	return free_pages_nr;
}

mali_bool mali_mem_swap_in_page_node(struct mali_page_node *page_node)
{
	MALI_DEBUG_ASSERT(NULL != page_node);

	page_node->swap_it->page = shmem_read_mapping_page(global_swap_space, page_node->swap_it->idx);

	if (IS_ERR(page_node->swap_it->page)) {
		MALI_DEBUG_PRINT_ERROR(("SWAP Mem: failed to swap in page with index: %d.\n", page_node->swap_it->idx));
		return MALI_FALSE;
	}

	/* Ensure page is flushed from CPU caches. */
	page_node->swap_it->dma_addr = dma_map_page(&mali_platform_device->dev, page_node->swap_it->page,
				       0, _MALI_OSK_MALI_PAGE_SIZE, DMA_TO_DEVICE);

	return MALI_TRUE;
}

int mali_mem_swap_alloc_pages(mali_mem_swap *swap_mem, u32 size, u32 *bkend_idx)
{
	size_t page_count = PAGE_ALIGN(size) / PAGE_SIZE;
	struct mali_page_node *m_page;
	long system_free_size;
	u32 i, index;
	mali_bool ret;

	MALI_DEBUG_ASSERT(NULL != swap_mem);
	MALI_DEBUG_ASSERT(NULL != bkend_idx);
	MALI_DEBUG_ASSERT(page_count <= MALI_SWAP_GLOBAL_SWAP_FILE_INDEX_RESERVE);

	if (atomic_read(&mali_mem_os_allocator.allocated_pages) * _MALI_OSK_MALI_PAGE_SIZE + size > mali_mem_os_allocator.allocation_limit) {
		MALI_DEBUG_PRINT(2, ("Mali Mem: Unable to allocate %u bytes. Currently allocated: %lu, max limit %lu\n",
				     size,
				     atomic_read(&mali_mem_os_allocator.allocated_pages) * _MALI_OSK_MALI_PAGE_SIZE,
				     mali_mem_os_allocator.allocation_limit));
		return _MALI_OSK_ERR_NOMEM;
	}

	INIT_LIST_HEAD(&swap_mem->pages);
	swap_mem->count = page_count;
	index = mali_mem_swap_idx_range_alloc(page_count);

	if (_MALI_OSK_BITMAP_INVALIDATE_INDEX == index) {
		MALI_PRINT_ERROR(("Mali Swap: Failed to allocate continuous index for swappable Mali memory."));
		return _MALI_OSK_ERR_FAULT;
	}

	for (i = 0; i < page_count; i++) {
		m_page = _mali_mem_swap_page_node_allocate();

		if (NULL == m_page) {
			MALI_DEBUG_PRINT_ERROR(("SWAP Mem: Failed to allocate mali page node."));
			swap_mem->count = i;

			mali_mem_swap_free(swap_mem);
			mali_mem_swap_idx_range_free(index + i, page_count - i);
			return _MALI_OSK_ERR_FAULT;
		}

		m_page->swap_it->idx = index + i;

		ret = mali_mem_swap_in_page_node(m_page);

		if (MALI_FALSE == ret) {
			MALI_DEBUG_PRINT_ERROR(("SWAP Mem: Allocate new page from SHMEM file failed."));
			_mali_mem_swap_page_node_free(m_page);
			mali_mem_swap_idx_range_free(index + i + 1, page_count - i - 1);

			swap_mem->count = i;
			mali_mem_swap_free(swap_mem);
			return _MALI_OSK_ERR_NOMEM;
		}

		list_add_tail(&m_page->list, &swap_mem->pages);
	}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)
	system_free_size = global_zone_page_state(NR_FREE_PAGES) * PAGE_SIZE;
#else
	system_free_size = global_page_state(NR_FREE_PAGES) * PAGE_SIZE;
#endif
        
	if ((system_free_size < mali_mem_swap_out_threshold_value)
	    && (mem_backend_swapped_pool_size > (mali_mem_swap_out_threshold_value >> 2))
	    && mali_utilization_enabled()) {
		_mali_osk_wq_schedule_work(mali_mem_swap_out_workq);
	}

	*bkend_idx = index;
	return 0;
}

void mali_mem_swap_mali_unmap(mali_mem_allocation *alloc)
{
	struct mali_session_data *session;

	MALI_DEBUG_ASSERT_POINTER(alloc);
	session = alloc->session;
	MALI_DEBUG_ASSERT_POINTER(session);

	mali_session_memory_lock(session);
	mali_mem_mali_map_free(session, alloc->psize, alloc->mali_vma_node.vm_node.start,
			       alloc->flags);
	mali_session_memory_unlock(session);
}


/* Insert these pages from shmem to mali page table*/
_mali_osk_errcode_t mali_mem_swap_mali_map(mali_mem_swap *swap_mem, struct mali_session_data *session, u32 vaddr, u32 props)
{
	struct mali_page_directory *pagedir = session->page_directory;
	struct mali_page_node *m_page;
	dma_addr_t phys;
	u32 virt = vaddr;
	u32 prop = props;

	list_for_each_entry(m_page, &swap_mem->pages, list) {
		MALI_DEBUG_ASSERT(NULL != m_page->swap_it->page);
		phys = m_page->swap_it->dma_addr;

		mali_mmu_pagedir_update(pagedir, virt, phys, MALI_MMU_PAGE_SIZE, prop);
		virt += MALI_MMU_PAGE_SIZE;
	}

	return _MALI_OSK_ERR_OK;
}

int mali_mem_swap_in_pages(struct mali_pp_job *job)
{
	u32 num_memory_cookies;
	struct mali_session_data *session;
	struct mali_vma_node *mali_vma_node = NULL;
	mali_mem_allocation *mali_alloc = NULL;
	mali_mem_backend *mem_bkend = NULL;
	struct mali_page_node *m_page;
	mali_bool swap_in_success = MALI_TRUE;
	int i;

	MALI_DEBUG_ASSERT_POINTER(job);

	num_memory_cookies = mali_pp_job_num_memory_cookies(job);
	session = mali_pp_job_get_session(job);

	MALI_DEBUG_ASSERT_POINTER(session);

	for (i = 0; i < num_memory_cookies; i++) {

		u32 mali_addr  = mali_pp_job_get_memory_cookie(job, i);

		mali_vma_node = mali_vma_offset_search(&session->allocation_mgr, mali_addr, 0);
		if (NULL == mali_vma_node) {
			job->memory_cookies[i] = MALI_SWAP_INVALIDATE_MALI_ADDRESS;
			swap_in_success = MALI_FALSE;
			MALI_PRINT_ERROR(("SWAP Mem: failed to find mali_vma_node through Mali address: 0x%08x.\n", mali_addr));
			continue;
		}

		mali_alloc = container_of(mali_vma_node, struct mali_mem_allocation, mali_vma_node);
		MALI_DEBUG_ASSERT(NULL != mali_alloc);

		if (MALI_MEM_SWAP != mali_alloc->type &&
		    MALI_MEM_COW != mali_alloc->type) {
			continue;
		}

		/* Get backend memory & Map on GPU */
		mutex_lock(&mali_idr_mutex);
		mem_bkend = idr_find(&mali_backend_idr, mali_alloc->backend_handle);
		mutex_unlock(&mali_idr_mutex);
		MALI_DEBUG_ASSERT(NULL != mem_bkend);

		/* We neednot hold backend's lock here, race safe.*/
		if ((MALI_MEM_COW == mem_bkend->type) &&
		    (!(mem_bkend->flags & MALI_MEM_BACKEND_FLAG_SWAP_COWED))) {
			continue;
		}

		mutex_lock(&mem_bkend->mutex);

		/* When swap_in_success is MALI_FALSE, it means this job has memory backend that could not be swapped in,
		 * and it will be aborted in mali scheduler, so here, we just mark those memory cookies which
		 * should not be swapped out when delete job to invalide */
		if (MALI_FALSE == swap_in_success) {
			job->memory_cookies[i] = MALI_SWAP_INVALIDATE_MALI_ADDRESS;
			mutex_unlock(&mem_bkend->mutex);
			continue;
		}

		/* Before swap in, checking if this memory backend has been swapped in by the latest flushed jobs. */
		++mem_bkend->using_count;

		if (1 < mem_bkend->using_count) {
			MALI_DEBUG_ASSERT(MALI_MEM_BACKEND_FLAG_UNSWAPPED_IN != (MALI_MEM_BACKEND_FLAG_UNSWAPPED_IN & mem_bkend->flags));
			mutex_unlock(&mem_bkend->mutex);
			continue;
		}

		if (MALI_MEM_BACKEND_FLAG_UNSWAPPED_IN != (MALI_MEM_BACKEND_FLAG_UNSWAPPED_IN & mem_bkend->flags)) {
			mutex_unlock(&mem_bkend->mutex);
			continue;
		}


		list_for_each_entry(m_page, &mem_bkend->swap_mem.pages, list) {
			if (MALI_FALSE == mali_mem_swap_in_page_node(m_page)) {
				/* Don't have enough memory to swap in page, so release pages have already been swapped
				 * in and then mark this pp job to be fail. */
				mali_mem_swap_unlock_partial_locked_mem_backend(mem_bkend, m_page);
				swap_in_success = MALI_FALSE;
				break;
			}
		}

		if (swap_in_success) {
#ifdef MALI_MEM_SWAP_TRACKING
			mem_backend_swapped_unlock_size -= mem_bkend->size;
#endif
			_mali_osk_mutex_wait(session->memory_lock);
			mali_mem_swap_mali_map(&mem_bkend->swap_mem, session, mali_alloc->mali_mapping.addr, mali_alloc->mali_mapping.properties);
			_mali_osk_mutex_signal(session->memory_lock);

			/* Remove the unlock flag from mem backend flags, mark this backend has been swapped in. */
			mem_bkend->flags &= ~(MALI_MEM_BACKEND_FLAG_UNSWAPPED_IN);
			mutex_unlock(&mem_bkend->mutex);
		} else {
			--mem_bkend->using_count;
			/* Marking that this backend is not swapped in, need not to be processed anymore. */
			job->memory_cookies[i] = MALI_SWAP_INVALIDATE_MALI_ADDRESS;
			mutex_unlock(&mem_bkend->mutex);
		}
	}

	job->swap_status = swap_in_success ? MALI_SWAP_IN_SUCC : MALI_SWAP_IN_FAIL;

	return _MALI_OSK_ERR_OK;
}

int mali_mem_swap_out_pages(struct mali_pp_job *job)
{
	u32 num_memory_cookies;
	struct mali_session_data *session;
	struct mali_vma_node *mali_vma_node = NULL;
	mali_mem_allocation *mali_alloc = NULL;
	mali_mem_backend *mem_bkend = NULL;
	int i;

	MALI_DEBUG_ASSERT_POINTER(job);

	num_memory_cookies = mali_pp_job_num_memory_cookies(job);
	session = mali_pp_job_get_session(job);

	MALI_DEBUG_ASSERT_POINTER(session);


	for (i = 0; i < num_memory_cookies; i++) {
		u32 mali_addr  = mali_pp_job_get_memory_cookie(job, i);

		if (MALI_SWAP_INVALIDATE_MALI_ADDRESS == mali_addr) {
			continue;
		}

		mali_vma_node = mali_vma_offset_search(&session->allocation_mgr, mali_addr, 0);

		if (NULL == mali_vma_node) {
			MALI_PRINT_ERROR(("SWAP Mem: failed to find mali_vma_node through Mali address: 0x%08x.\n", mali_addr));
			continue;
		}

		mali_alloc = container_of(mali_vma_node, struct mali_mem_allocation, mali_vma_node);
		MALI_DEBUG_ASSERT(NULL != mali_alloc);

		if (MALI_MEM_SWAP != mali_alloc->type &&
		    MALI_MEM_COW != mali_alloc->type) {
			continue;
		}

		mutex_lock(&mali_idr_mutex);
		mem_bkend = idr_find(&mali_backend_idr, mali_alloc->backend_handle);
		mutex_unlock(&mali_idr_mutex);
		MALI_DEBUG_ASSERT(NULL != mem_bkend);

		/* We neednot hold backend's lock here, race safe.*/
		if ((MALI_MEM_COW == mem_bkend->type) &&
		    (!(mem_bkend->flags & MALI_MEM_BACKEND_FLAG_SWAP_COWED))) {
			continue;
		}

		mutex_lock(&mem_bkend->mutex);

		MALI_DEBUG_ASSERT(0 < mem_bkend->using_count);

		/* Reducing the using_count of mem backend means less pp job are using this memory backend,
		 * if this count get to zero, it means no pp job is using it now, could put it to swap out list. */
		--mem_bkend->using_count;

		if (0 < mem_bkend->using_count) {
			mutex_unlock(&mem_bkend->mutex);
			continue;
		}
		mutex_unlock(&mem_bkend->mutex);

		mali_memory_swap_list_backend_add(mem_bkend);
	}

	return _MALI_OSK_ERR_OK;
}

int mali_mem_swap_allocate_page_on_demand(mali_mem_backend *mem_bkend, u32 offset, struct page **pagep)
{
	struct mali_page_node *m_page, *found_node = NULL;
	struct page *found_page;
	mali_mem_swap *swap = NULL;
	mali_mem_cow *cow = NULL;
	dma_addr_t dma_addr;
	u32 i = 0;

	if (MALI_MEM_SWAP == mem_bkend->type) {
		swap = &mem_bkend->swap_mem;
		list_for_each_entry(m_page, &swap->pages, list) {
			if (i == offset) {
				found_node = m_page;
				break;
			}
			i++;
		}
	} else {
		MALI_DEBUG_ASSERT(MALI_MEM_COW == mem_bkend->type);
		MALI_DEBUG_ASSERT(MALI_MEM_BACKEND_FLAG_SWAP_COWED == (MALI_MEM_BACKEND_FLAG_SWAP_COWED & mem_bkend->flags));

		cow = &mem_bkend->cow_mem;
		list_for_each_entry(m_page, &cow->pages, list) {
			if (i == offset) {
				found_node = m_page;
				break;
			}
			i++;
		}
	}

	if (NULL == found_node) {
		return _MALI_OSK_ERR_FAULT;
	}

	found_page = shmem_read_mapping_page(global_swap_space, found_node->swap_it->idx);

	if (!IS_ERR(found_page)) {
		lock_page(found_page);
		dma_addr = dma_map_page(&mali_platform_device->dev, found_page,
					0, _MALI_OSK_MALI_PAGE_SIZE, DMA_TO_DEVICE);
		dma_unmap_page(&mali_platform_device->dev, dma_addr,
			       _MALI_OSK_MALI_PAGE_SIZE, DMA_TO_DEVICE);

		*pagep = found_page;
	} else {
		return _MALI_OSK_ERR_NOMEM;
	}

	return _MALI_OSK_ERR_OK;
}

int mali_mem_swap_cow_page_on_demand(mali_mem_backend *mem_bkend, u32 offset, struct page **pagep)
{
	struct mali_page_node *m_page, *found_node = NULL, *new_node = NULL;
	mali_mem_cow *cow = NULL;
	u32 i = 0;

	MALI_DEBUG_ASSERT(MALI_MEM_COW == mem_bkend->type);
	MALI_DEBUG_ASSERT(MALI_MEM_BACKEND_FLAG_SWAP_COWED == (mem_bkend->flags & MALI_MEM_BACKEND_FLAG_SWAP_COWED));
	MALI_DEBUG_ASSERT(MALI_MEM_BACKEND_FLAG_UNSWAPPED_IN == (MALI_MEM_BACKEND_FLAG_UNSWAPPED_IN & mem_bkend->flags));
	MALI_DEBUG_ASSERT(!mali_memory_swap_backend_in_swapped_pool(mem_bkend));

	cow = &mem_bkend->cow_mem;
	list_for_each_entry(m_page, &cow->pages, list) {
		if (i == offset) {
			found_node = m_page;
			break;
		}
		i++;
	}

	if (NULL == found_node) {
		return _MALI_OSK_ERR_FAULT;
	}

	new_node = _mali_mem_swap_page_node_allocate();

	if (NULL == new_node) {
		return _MALI_OSK_ERR_FAULT;
	}

	new_node->swap_it->idx = mali_mem_swap_idx_alloc();

	if (_MALI_OSK_BITMAP_INVALIDATE_INDEX == new_node->swap_it->idx) {
		MALI_DEBUG_PRINT(1, ("Failed to allocate swap index in swap CoW on demand.\n"));
		kfree(new_node->swap_it);
		kfree(new_node);
		return _MALI_OSK_ERR_FAULT;
	}

	if (MALI_FALSE == mali_mem_swap_in_page_node(new_node)) {
		_mali_mem_swap_page_node_free(new_node);
		return _MALI_OSK_ERR_FAULT;
	}

	/* swap in found node for copy in kernel. */
	if (MALI_FALSE == mali_mem_swap_in_page_node(found_node)) {
		mali_mem_swap_out_page_node(new_node);
		_mali_mem_swap_page_node_free(new_node);
		return _MALI_OSK_ERR_FAULT;
	}

	_mali_mem_cow_copy_page(found_node, new_node);

	list_replace(&found_node->list, &new_node->list);

	if (1 != _mali_page_node_get_ref_count(found_node)) {
		atomic_add(1, &mem_bkend->mali_allocation->session->mali_mem_allocated_pages);
		if (atomic_read(&mem_bkend->mali_allocation->session->mali_mem_allocated_pages) * MALI_MMU_PAGE_SIZE > mem_bkend->mali_allocation->session->max_mali_mem_allocated_size) {
			mem_bkend->mali_allocation->session->max_mali_mem_allocated_size = atomic_read(&mem_bkend->mali_allocation->session->mali_mem_allocated_pages) * MALI_MMU_PAGE_SIZE;
		}
		mem_bkend->cow_mem.change_pages_nr++;
	}

	mali_mem_swap_out_page_node(found_node);
	_mali_mem_swap_page_node_free(found_node);

	/* When swap in the new page node, we have called dma_map_page for this page.\n */
	dma_unmap_page(&mali_platform_device->dev, new_node->swap_it->dma_addr,
		       _MALI_OSK_MALI_PAGE_SIZE, DMA_TO_DEVICE);

	lock_page(new_node->swap_it->page);

	*pagep = new_node->swap_it->page;

	return _MALI_OSK_ERR_OK;
}

#ifdef MALI_MEM_SWAP_TRACKING
void mali_mem_swap_tracking(u32 *swap_pool_size, u32 *unlock_size)
{
	*swap_pool_size = mem_backend_swapped_pool_size;
	*unlock_size =  mem_backend_swapped_unlock_size;
}
#endif
