/*
 * mm/low-mem-notify.c
 *
 * Sends low-memory notifications to processes via /dev/low-mem.
 *
 * Copyright (C) 2012 The Chromium OS Authors
 * This program is free software, released under the GPL.
 * Based on a proposal by Minchan Kim
 *
 * A process that polls /dev/low-mem is notified of a low-memory situation.
 * The intent is to allow the process to free some memory before the OOM killer
 * is invoked.
 *
 * A low-memory condition is estimated by subtracting anonymous memory
 * (i.e. process data segments), kernel memory, and a fixed amount of
 * file-backed memory from total memory.  This is just a heuristic, as in
 * general we don't know how much memory can be reclaimed before we try to
 * reclaim it, and that's too expensive or too late.
 *
 * This is tailored to Chromium OS, where a single program (the browser)
 * controls most of the memory, and (currently) no swap space is used.
 */


#include <linux/low-mem-notify.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/wait.h>
#include <linux/poll.h>
#include <linux/slab.h>
#include <linux/mm.h>

static DECLARE_WAIT_QUEUE_HEAD(low_mem_wait);
static atomic_t low_mem_state = ATOMIC_INIT(0);
unsigned low_mem_margin_mb = 50;
bool low_mem_margin_enabled = true;
unsigned long low_mem_minfree;
unsigned int low_mem_ram_vs_swap_weight = 4;

/* Limit logging low memory to once per second. */
DEFINE_RATELIMIT_STATE(low_mem_logging_ratelimit, 1 * HZ, 1);

struct low_mem_notify_file_info {
	unsigned long unused;
};

void low_mem_notify(void)
{
	atomic_set(&low_mem_state, true);
	wake_up(&low_mem_wait);
}

static int low_mem_notify_open(struct inode *inode, struct file *file)
{
	struct low_mem_notify_file_info *info;
	int err = 0;

	info = kmalloc(sizeof(*info), GFP_KERNEL);
	if (!info) {
		err = -ENOMEM;
		goto out;
	}

	file->private_data = info;
out:
	return err;
}

static int low_mem_notify_release(struct inode *inode, struct file *file)
{
	kfree(file->private_data);
	return 0;
}

static unsigned int low_mem_notify_poll(struct file *file, poll_table *wait)
{
	unsigned int ret = 0;

	/* Update state to reflect any recent freeing. */
	atomic_set(&low_mem_state, is_low_mem_situation());

	poll_wait(file, &low_mem_wait, wait);

	if (low_mem_margin_enabled && atomic_read(&low_mem_state) != 0)
		ret = POLLIN;

	return ret;
}

const struct file_operations low_mem_notify_fops = {
	.open = low_mem_notify_open,
	.release = low_mem_notify_release,
	.poll = low_mem_notify_poll,
};
EXPORT_SYMBOL(low_mem_notify_fops);

#ifdef CONFIG_SYSFS

#define LOW_MEM_ATTR(_name)				      \
	static struct kobj_attribute low_mem_##_name##_attr = \
		__ATTR(_name, 0644, low_mem_##_name##_show,   \
		       low_mem_##_name##_store)

static ssize_t low_mem_margin_show(struct kobject *kobj,
				  struct kobj_attribute *attr, char *buf)
{
	if (low_mem_margin_enabled)
		return sprintf(buf, "%u\n", low_mem_margin_mb);
	else
		return sprintf(buf, "off\n");
}

static unsigned low_mem_margin_to_minfree(unsigned margin_mb)
{
	return margin_mb * (1024 * 1024 / PAGE_SIZE);
}

static ssize_t low_mem_margin_store(struct kobject *kobj,
				    struct kobj_attribute *attr,
				    const char *buf, size_t count)
{
	int err;
	unsigned long margin;
	/*
	 * Even though the API does not say anything about this, the string in
	 * buf is zero-terminated (as long as count < PAGE_SIZE) because buf is
	 * a newly allocated zero-filled page.  Most other sysfs handlers rely
	 * on this too.
	 */
	if (strncmp("off", buf, 3) == 0) {
		pr_info("low_mem: disabling notifier\n");
		low_mem_margin_enabled = false;
		return count;
	}
	if (strncmp("on", buf, 2) == 0) {
		pr_info("low_mem: enabling notifier\n");
		low_mem_margin_enabled = true;
		return count;
	}

	err = kstrtoul(buf, 10, &margin);
	if (err)
		return -EINVAL;
	if (margin * ((1024 * 1024) / PAGE_SIZE) > totalram_pages)
		return -EINVAL;
	/* Notify when the "free" memory is below margin megabytes. */
	low_mem_margin_enabled = true;
	low_mem_margin_mb = (unsigned int) margin;
	/* Convert to pages outside the allocator fast path. */
	low_mem_minfree = low_mem_margin_to_minfree(low_mem_margin_mb);
	pr_info("low_mem: setting minfree to %lu kB\n",
		low_mem_minfree * (PAGE_SIZE / 1024));
	return count;
}
LOW_MEM_ATTR(margin);

static ssize_t low_mem_ram_vs_swap_weight_show(struct kobject *kobj,
					       struct kobj_attribute *attr,
					       char *buf)
{
	return sprintf(buf, "%u\n", low_mem_ram_vs_swap_weight);
}

static ssize_t low_mem_ram_vs_swap_weight_store(struct kobject *kobj,
						struct kobj_attribute *attr,
						const char *buf, size_t count)
{
	unsigned long weight;
	int err;

	err = kstrtoul(buf, 10, &weight);
	if (err)
		return -EINVAL;
	/* The special value 0 represents infinity. */
	low_mem_ram_vs_swap_weight = weight == 0 ?
		-1U : (unsigned int) weight;
	pr_info("low_mem: setting ram weight to %u\n",
		low_mem_ram_vs_swap_weight);
	return count;
}
LOW_MEM_ATTR(ram_vs_swap_weight);

static ssize_t low_mem_available_show(struct kobject *kobj,
				      struct kobj_attribute *attr,
				      char *buf)
{
	unsigned long available_mem = get_available_mem_adj();

	return sprintf(buf, "%lu\n",
		       available_mem / (1024 * 1024 / PAGE_SIZE));
}

static ssize_t low_mem_available_store(struct kobject *kobj,
				       struct kobj_attribute *attr,
				       const char *buf, size_t count)
{
	return -EINVAL;
}
LOW_MEM_ATTR(available);

static struct attribute *low_mem_attrs[] = {
	&low_mem_margin_attr.attr,
	&low_mem_ram_vs_swap_weight_attr.attr,
	&low_mem_available_attr.attr,
	NULL,
};

static struct attribute_group low_mem_attr_group = {
	.attrs = low_mem_attrs,
	.name = "chromeos-low_mem",
};

static int __init low_mem_init(void)
{
	int err = sysfs_create_group(mm_kobj, &low_mem_attr_group);
	if (err)
		pr_err("low_mem: register sysfs failed\n");
	low_mem_minfree = low_mem_margin_to_minfree(low_mem_margin_mb);
	return err;
}
module_init(low_mem_init)

#endif
