All of lore.kernel.org
 help / color / mirror / Atom feed
From: Greg KH <gregkh@linuxfoundation.org>
To: peter.enderborg@sonymobile.com
Cc: devel@driverdev.osuosl.org, linux-kernel@vger.kernel.org,
	arve@android.com, riandrews@android.com,
	torvalds@linux-foundation.org, linux-mm@kvack.org
Subject: Re: [PATCH 1/3 staging-next] android: Collect statistics from lowmemorykiller
Date: Tue, 14 Feb 2017 08:50:15 -0800	[thread overview]
Message-ID: <20170214165015.GD17335@kroah.com> (raw)
In-Reply-To: <20170214160932.4988-1-peter.enderborg@sonymobile.com>

On Tue, Feb 14, 2017 at 05:09:30PM +0100, peter.enderborg@sonymobile.com wrote:
> From: Peter Enderborg <peter.enderborg@sonymobile.com>
> 
> This collects stats for shrinker calls and how much
> waste work we do within the lowmemorykiller.
> 
> Signed-off-by: Peter Enderborg <peter.enderborg@sonymobile.com>
> ---
>  drivers/staging/android/Kconfig                 | 11 ++++
>  drivers/staging/android/Makefile                |  1 +
>  drivers/staging/android/lowmemorykiller.c       |  9 ++-
>  drivers/staging/android/lowmemorykiller_stats.c | 85 +++++++++++++++++++++++++
>  drivers/staging/android/lowmemorykiller_stats.h | 29 +++++++++
>  5 files changed, 134 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/staging/android/lowmemorykiller_stats.c
>  create mode 100644 drivers/staging/android/lowmemorykiller_stats.h
> 
> diff --git a/drivers/staging/android/Kconfig b/drivers/staging/android/Kconfig
> index 6c00d6f..96e86c7 100644
> --- a/drivers/staging/android/Kconfig
> +++ b/drivers/staging/android/Kconfig
> @@ -24,6 +24,17 @@ config ANDROID_LOW_MEMORY_KILLER
>  	  scripts (/init.rc), and it defines priority values with minimum free memory size
>  	  for each priority.
>  
> +config ANDROID_LOW_MEMORY_KILLER_STATS
> +	bool "Android Low Memory Killer: collect statistics"
> +	depends on ANDROID_LOW_MEMORY_KILLER
> +	default n
> +	help
> +	  Create a file in /proc/lmkstats that includes
> +	  collected statistics about kills, scans and counts
> +	  and  interaction with the shrinker. Its content
> +	  will be different depeding on lmk implementation used.

Ick, no new /proc files please, this isn't a "process" value.  What's
wrong with debugfs?

Also note the minor '  ' usage in your first sentence of the help text.

>  source "drivers/staging/android/ion/Kconfig"
>  
>  endif # if ANDROID
> diff --git a/drivers/staging/android/Makefile b/drivers/staging/android/Makefile
> index 7ed1be7..d710eb2 100644
> --- a/drivers/staging/android/Makefile
> +++ b/drivers/staging/android/Makefile
> @@ -4,3 +4,4 @@ obj-y					+= ion/
>  
>  obj-$(CONFIG_ASHMEM)			+= ashmem.o
>  obj-$(CONFIG_ANDROID_LOW_MEMORY_KILLER)	+= lowmemorykiller.o
> +obj-$(CONFIG_ANDROID_LOW_MEMORY_KILLER_STATS)	+= lowmemorykiller_stats.o
> diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c
> index ec3b665..15c1b38 100644
> --- a/drivers/staging/android/lowmemorykiller.c
> +++ b/drivers/staging/android/lowmemorykiller.c
> @@ -42,6 +42,7 @@
>  #include <linux/rcupdate.h>
>  #include <linux/profile.h>
>  #include <linux/notifier.h>
> +#include "lowmemorykiller_stats.h"
>  
>  static u32 lowmem_debug_level = 1;
>  static short lowmem_adj[6] = {
> @@ -72,6 +73,7 @@ static unsigned long lowmem_deathpending_timeout;
>  static unsigned long lowmem_count(struct shrinker *s,
>  				  struct shrink_control *sc)
>  {
> +	lmk_inc_stats(LMK_COUNT);
>  	return global_node_page_state(NR_ACTIVE_ANON) +
>  		global_node_page_state(NR_ACTIVE_FILE) +
>  		global_node_page_state(NR_INACTIVE_ANON) +
> @@ -95,6 +97,7 @@ static unsigned long lowmem_scan(struct shrinker *s, struct shrink_control *sc)
>  				global_node_page_state(NR_SHMEM) -
>  				total_swapcache_pages();
>  
> +	lmk_inc_stats(LMK_SCAN);
>  	if (lowmem_adj_size < array_size)
>  		array_size = lowmem_adj_size;
>  	if (lowmem_minfree_size < array_size)
> @@ -134,6 +137,7 @@ static unsigned long lowmem_scan(struct shrinker *s, struct shrink_control *sc)
>  		if (task_lmk_waiting(p) &&
>  		    time_before_eq(jiffies, lowmem_deathpending_timeout)) {
>  			task_unlock(p);
> +			lmk_inc_stats(LMK_TIMEOUT);
>  			rcu_read_unlock();
>  			return 0;
>  		}
> @@ -179,7 +183,9 @@ static unsigned long lowmem_scan(struct shrinker *s, struct shrink_control *sc)
>  			     other_free * (long)(PAGE_SIZE / 1024));
>  		lowmem_deathpending_timeout = jiffies + HZ;
>  		rem += selected_tasksize;
> -	}
> +		lmk_inc_stats(LMK_KILL);
> +	} else
> +		lmk_inc_stats(LMK_WASTE);
>  
>  	lowmem_print(4, "lowmem_scan %lu, %x, return %lu\n",
>  		     sc->nr_to_scan, sc->gfp_mask, rem);
> @@ -196,6 +202,7 @@ static struct shrinker lowmem_shrinker = {
>  static int __init lowmem_init(void)
>  {
>  	register_shrinker(&lowmem_shrinker);
> +	init_procfs_lmk();
>  	return 0;
>  }
>  device_initcall(lowmem_init);
> diff --git a/drivers/staging/android/lowmemorykiller_stats.c b/drivers/staging/android/lowmemorykiller_stats.c
> new file mode 100644
> index 0000000..673691c
> --- /dev/null
> +++ b/drivers/staging/android/lowmemorykiller_stats.c
> @@ -0,0 +1,85 @@
> +/*
> + *  lowmemorykiller_stats
> + *
> + *  Copyright (C) 2017 Sony Mobile Communications Inc.
> + *
> + *  Author: Peter Enderborg <peter.enderborg@sonymobile.com>
> + *
> + *  This program is free software; you can redistribute it and/or modify
> + *  it under the terms of the GNU General Public License version 2 as
> + *  published by the Free Software Foundation.
> + */
> +/* This code is bookkeeping of statistical information
> + * from lowmemorykiller and provide a node in proc "/proc/lmkstats".
> + */
> +
> +#include <linux/proc_fs.h>
> +#include <linux/seq_file.h>
> +#include "lowmemorykiller_stats.h"
> +
> +struct lmk_stats {
> +	atomic_long_t scans; /* counter as in shrinker scans */
> +	atomic_long_t kills; /* the number of sigkills sent */
> +	atomic_long_t waste; /* the numer of extensive calls that did
> +			      * not lead to anything
> +			      */
> +	atomic_long_t timeout; /* counter for shrinker calls that needed
> +				* to be cancelled due to pending kills
> +				*/
> +	atomic_long_t count; /* number of shrinker count calls */
> +	atomic_long_t unknown; /* internal */

Why not document the structure in the proper kernel-doc format?

Also, do you really need atomic variables here?

> +} st;
> +
> +void lmk_inc_stats(int key)
> +{
> +	switch (key) {
> +	case LMK_SCAN:
> +		atomic_long_inc(&st.scans);
> +		break;
> +	case LMK_KILL:
> +		atomic_long_inc(&st.kills);
> +		break;
> +	case LMK_WASTE:
> +		atomic_long_inc(&st.waste);
> +		break;
> +	case LMK_TIMEOUT:
> +		atomic_long_inc(&st.timeout);
> +		break;
> +	case LMK_COUNT:
> +		atomic_long_inc(&st.count);
> +		break;
> +	default:
> +		atomic_long_inc(&st.unknown);
> +		break;
> +	}
> +}
> +
> +static int lmk_proc_show(struct seq_file *m, void *v)
> +{
> +	seq_printf(m, "kill: %ld\n", atomic_long_read(&st.kills));
> +	seq_printf(m, "scan: %ld\n", atomic_long_read(&st.scans));
> +	seq_printf(m, "waste: %ld\n", atomic_long_read(&st.waste));
> +	seq_printf(m, "timeout: %ld\n", atomic_long_read(&st.timeout));
> +	seq_printf(m, "count: %ld\n", atomic_long_read(&st.count));
> +	seq_printf(m, "unknown: %ld (internal)\n",
> +		   atomic_long_read(&st.unknown));
> +
> +	return 0;
> +}
> +
> +static int lmk_proc_open(struct inode *inode, struct file *file)
> +{
> +	return single_open(file, lmk_proc_show, PDE_DATA(inode));
> +}
> +
> +static const struct file_operations lmk_proc_fops = {
> +	.open		= lmk_proc_open,
> +	.read		= seq_read,
> +	.release	= single_release
> +};
> +
> +int __init init_procfs_lmk(void)
> +{
> +	proc_create_data(LMK_PROCFS_NAME, 0444, NULL, &lmk_proc_fops, NULL);
> +	return 0;
> +}
> diff --git a/drivers/staging/android/lowmemorykiller_stats.h b/drivers/staging/android/lowmemorykiller_stats.h
> new file mode 100644
> index 0000000..abeb6924
> --- /dev/null
> +++ b/drivers/staging/android/lowmemorykiller_stats.h
> @@ -0,0 +1,29 @@
> +/*
> + *  lowmemorykiller_stats interface
> + *
> + *  Copyright (C) 2017 Sony Mobile Communications Inc.
> + *
> + *  Author: Peter Enderborg <peter.enderborg@sonymobile.com>
> + *
> + *  This program is free software; you can redistribute it and/or modify
> + *  it under the terms of the GNU General Public License version 2 as
> + *  published by the Free Software Foundation.
> + */
> +
> +enum  lmk_kill_stats {

nit, two spaces?

> +	LMK_SCAN = 1,
> +	LMK_KILL = 2,
> +	LMK_WASTE = 3,
> +	LMK_TIMEOUT = 4,
> +	LMK_COUNT = 5
> +};
> +
> +#define LMK_PROCFS_NAME "lmkstats"

You only use it once, why create a #define?  Anyway, debugfs is better
for debugging stuff like this, that is what it was created for.

thanks,

greg k-h

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

WARNING: multiple messages have this Message-ID (diff)
From: Greg KH <gregkh@linuxfoundation.org>
To: peter.enderborg@sonymobile.com
Cc: devel@driverdev.osuosl.org, linux-kernel@vger.kernel.org,
	arve@android.com, riandrews@android.com,
	torvalds@linux-foundation.org, linux-mm@kvack.org
Subject: Re: [PATCH 1/3 staging-next] android: Collect statistics from lowmemorykiller
Date: Tue, 14 Feb 2017 08:50:15 -0800	[thread overview]
Message-ID: <20170214165015.GD17335@kroah.com> (raw)
In-Reply-To: <20170214160932.4988-1-peter.enderborg@sonymobile.com>

On Tue, Feb 14, 2017 at 05:09:30PM +0100, peter.enderborg@sonymobile.com wrote:
> From: Peter Enderborg <peter.enderborg@sonymobile.com>
> 
> This collects stats for shrinker calls and how much
> waste work we do within the lowmemorykiller.
> 
> Signed-off-by: Peter Enderborg <peter.enderborg@sonymobile.com>
> ---
>  drivers/staging/android/Kconfig                 | 11 ++++
>  drivers/staging/android/Makefile                |  1 +
>  drivers/staging/android/lowmemorykiller.c       |  9 ++-
>  drivers/staging/android/lowmemorykiller_stats.c | 85 +++++++++++++++++++++++++
>  drivers/staging/android/lowmemorykiller_stats.h | 29 +++++++++
>  5 files changed, 134 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/staging/android/lowmemorykiller_stats.c
>  create mode 100644 drivers/staging/android/lowmemorykiller_stats.h
> 
> diff --git a/drivers/staging/android/Kconfig b/drivers/staging/android/Kconfig
> index 6c00d6f..96e86c7 100644
> --- a/drivers/staging/android/Kconfig
> +++ b/drivers/staging/android/Kconfig
> @@ -24,6 +24,17 @@ config ANDROID_LOW_MEMORY_KILLER
>  	  scripts (/init.rc), and it defines priority values with minimum free memory size
>  	  for each priority.
>  
> +config ANDROID_LOW_MEMORY_KILLER_STATS
> +	bool "Android Low Memory Killer: collect statistics"
> +	depends on ANDROID_LOW_MEMORY_KILLER
> +	default n
> +	help
> +	  Create a file in /proc/lmkstats that includes
> +	  collected statistics about kills, scans and counts
> +	  and  interaction with the shrinker. Its content
> +	  will be different depeding on lmk implementation used.

Ick, no new /proc files please, this isn't a "process" value.  What's
wrong with debugfs?

Also note the minor '  ' usage in your first sentence of the help text.

>  source "drivers/staging/android/ion/Kconfig"
>  
>  endif # if ANDROID
> diff --git a/drivers/staging/android/Makefile b/drivers/staging/android/Makefile
> index 7ed1be7..d710eb2 100644
> --- a/drivers/staging/android/Makefile
> +++ b/drivers/staging/android/Makefile
> @@ -4,3 +4,4 @@ obj-y					+= ion/
>  
>  obj-$(CONFIG_ASHMEM)			+= ashmem.o
>  obj-$(CONFIG_ANDROID_LOW_MEMORY_KILLER)	+= lowmemorykiller.o
> +obj-$(CONFIG_ANDROID_LOW_MEMORY_KILLER_STATS)	+= lowmemorykiller_stats.o
> diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c
> index ec3b665..15c1b38 100644
> --- a/drivers/staging/android/lowmemorykiller.c
> +++ b/drivers/staging/android/lowmemorykiller.c
> @@ -42,6 +42,7 @@
>  #include <linux/rcupdate.h>
>  #include <linux/profile.h>
>  #include <linux/notifier.h>
> +#include "lowmemorykiller_stats.h"
>  
>  static u32 lowmem_debug_level = 1;
>  static short lowmem_adj[6] = {
> @@ -72,6 +73,7 @@ static unsigned long lowmem_deathpending_timeout;
>  static unsigned long lowmem_count(struct shrinker *s,
>  				  struct shrink_control *sc)
>  {
> +	lmk_inc_stats(LMK_COUNT);
>  	return global_node_page_state(NR_ACTIVE_ANON) +
>  		global_node_page_state(NR_ACTIVE_FILE) +
>  		global_node_page_state(NR_INACTIVE_ANON) +
> @@ -95,6 +97,7 @@ static unsigned long lowmem_scan(struct shrinker *s, struct shrink_control *sc)
>  				global_node_page_state(NR_SHMEM) -
>  				total_swapcache_pages();
>  
> +	lmk_inc_stats(LMK_SCAN);
>  	if (lowmem_adj_size < array_size)
>  		array_size = lowmem_adj_size;
>  	if (lowmem_minfree_size < array_size)
> @@ -134,6 +137,7 @@ static unsigned long lowmem_scan(struct shrinker *s, struct shrink_control *sc)
>  		if (task_lmk_waiting(p) &&
>  		    time_before_eq(jiffies, lowmem_deathpending_timeout)) {
>  			task_unlock(p);
> +			lmk_inc_stats(LMK_TIMEOUT);
>  			rcu_read_unlock();
>  			return 0;
>  		}
> @@ -179,7 +183,9 @@ static unsigned long lowmem_scan(struct shrinker *s, struct shrink_control *sc)
>  			     other_free * (long)(PAGE_SIZE / 1024));
>  		lowmem_deathpending_timeout = jiffies + HZ;
>  		rem += selected_tasksize;
> -	}
> +		lmk_inc_stats(LMK_KILL);
> +	} else
> +		lmk_inc_stats(LMK_WASTE);
>  
>  	lowmem_print(4, "lowmem_scan %lu, %x, return %lu\n",
>  		     sc->nr_to_scan, sc->gfp_mask, rem);
> @@ -196,6 +202,7 @@ static struct shrinker lowmem_shrinker = {
>  static int __init lowmem_init(void)
>  {
>  	register_shrinker(&lowmem_shrinker);
> +	init_procfs_lmk();
>  	return 0;
>  }
>  device_initcall(lowmem_init);
> diff --git a/drivers/staging/android/lowmemorykiller_stats.c b/drivers/staging/android/lowmemorykiller_stats.c
> new file mode 100644
> index 0000000..673691c
> --- /dev/null
> +++ b/drivers/staging/android/lowmemorykiller_stats.c
> @@ -0,0 +1,85 @@
> +/*
> + *  lowmemorykiller_stats
> + *
> + *  Copyright (C) 2017 Sony Mobile Communications Inc.
> + *
> + *  Author: Peter Enderborg <peter.enderborg@sonymobile.com>
> + *
> + *  This program is free software; you can redistribute it and/or modify
> + *  it under the terms of the GNU General Public License version 2 as
> + *  published by the Free Software Foundation.
> + */
> +/* This code is bookkeeping of statistical information
> + * from lowmemorykiller and provide a node in proc "/proc/lmkstats".
> + */
> +
> +#include <linux/proc_fs.h>
> +#include <linux/seq_file.h>
> +#include "lowmemorykiller_stats.h"
> +
> +struct lmk_stats {
> +	atomic_long_t scans; /* counter as in shrinker scans */
> +	atomic_long_t kills; /* the number of sigkills sent */
> +	atomic_long_t waste; /* the numer of extensive calls that did
> +			      * not lead to anything
> +			      */
> +	atomic_long_t timeout; /* counter for shrinker calls that needed
> +				* to be cancelled due to pending kills
> +				*/
> +	atomic_long_t count; /* number of shrinker count calls */
> +	atomic_long_t unknown; /* internal */

Why not document the structure in the proper kernel-doc format?

Also, do you really need atomic variables here?

> +} st;
> +
> +void lmk_inc_stats(int key)
> +{
> +	switch (key) {
> +	case LMK_SCAN:
> +		atomic_long_inc(&st.scans);
> +		break;
> +	case LMK_KILL:
> +		atomic_long_inc(&st.kills);
> +		break;
> +	case LMK_WASTE:
> +		atomic_long_inc(&st.waste);
> +		break;
> +	case LMK_TIMEOUT:
> +		atomic_long_inc(&st.timeout);
> +		break;
> +	case LMK_COUNT:
> +		atomic_long_inc(&st.count);
> +		break;
> +	default:
> +		atomic_long_inc(&st.unknown);
> +		break;
> +	}
> +}
> +
> +static int lmk_proc_show(struct seq_file *m, void *v)
> +{
> +	seq_printf(m, "kill: %ld\n", atomic_long_read(&st.kills));
> +	seq_printf(m, "scan: %ld\n", atomic_long_read(&st.scans));
> +	seq_printf(m, "waste: %ld\n", atomic_long_read(&st.waste));
> +	seq_printf(m, "timeout: %ld\n", atomic_long_read(&st.timeout));
> +	seq_printf(m, "count: %ld\n", atomic_long_read(&st.count));
> +	seq_printf(m, "unknown: %ld (internal)\n",
> +		   atomic_long_read(&st.unknown));
> +
> +	return 0;
> +}
> +
> +static int lmk_proc_open(struct inode *inode, struct file *file)
> +{
> +	return single_open(file, lmk_proc_show, PDE_DATA(inode));
> +}
> +
> +static const struct file_operations lmk_proc_fops = {
> +	.open		= lmk_proc_open,
> +	.read		= seq_read,
> +	.release	= single_release
> +};
> +
> +int __init init_procfs_lmk(void)
> +{
> +	proc_create_data(LMK_PROCFS_NAME, 0444, NULL, &lmk_proc_fops, NULL);
> +	return 0;
> +}
> diff --git a/drivers/staging/android/lowmemorykiller_stats.h b/drivers/staging/android/lowmemorykiller_stats.h
> new file mode 100644
> index 0000000..abeb6924
> --- /dev/null
> +++ b/drivers/staging/android/lowmemorykiller_stats.h
> @@ -0,0 +1,29 @@
> +/*
> + *  lowmemorykiller_stats interface
> + *
> + *  Copyright (C) 2017 Sony Mobile Communications Inc.
> + *
> + *  Author: Peter Enderborg <peter.enderborg@sonymobile.com>
> + *
> + *  This program is free software; you can redistribute it and/or modify
> + *  it under the terms of the GNU General Public License version 2 as
> + *  published by the Free Software Foundation.
> + */
> +
> +enum  lmk_kill_stats {

nit, two spaces?

> +	LMK_SCAN = 1,
> +	LMK_KILL = 2,
> +	LMK_WASTE = 3,
> +	LMK_TIMEOUT = 4,
> +	LMK_COUNT = 5
> +};
> +
> +#define LMK_PROCFS_NAME "lmkstats"

You only use it once, why create a #define?  Anyway, debugfs is better
for debugging stuff like this, that is what it was created for.

thanks,

greg k-h

  parent reply	other threads:[~2017-02-14 16:50 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-02-14 16:09 [PATCH 1/3 staging-next] android: Collect statistics from lowmemorykiller peter.enderborg
2017-02-14 16:09 ` peter.enderborg
2017-02-14 16:09 ` [PATCH 2/3 staging-next] oom: Add notification for oom_score_adj peter.enderborg
2017-02-14 16:09   ` peter.enderborg
2017-02-14 16:09 ` [PATCH 3/3 staging-next] mm: Remove RCU and tasklocks from lmk peter.enderborg
2017-02-14 16:09   ` peter.enderborg
2017-02-14 16:50 ` Greg KH [this message]
2017-02-14 16:50   ` [PATCH 1/3 staging-next] android: Collect statistics from lowmemorykiller Greg KH
2017-02-15  8:22   ` peter enderborg
2017-02-15  8:22     ` peter enderborg
2017-02-15 14:29     ` Greg KH
2017-02-15 14:29       ` Greg KH
2017-02-14 16:51 ` Greg KH
2017-02-14 16:51   ` Greg KH
2017-02-15  8:21   ` peter enderborg
2017-02-15  8:21     ` peter enderborg
2017-02-15 14:31     ` Greg KH
2017-02-15 14:31       ` Greg KH
  -- strict thread matches above, loose matches on Subject: below --
2017-02-09 13:21 peter enderborg
2017-02-09 13:21 ` peter enderborg
2017-02-09 13:50 ` Greg Kroah-Hartman
2017-02-09 13:50   ` Greg Kroah-Hartman
2017-02-09 19:26 ` Michal Hocko
2017-02-09 19:26   ` Michal Hocko
2017-02-09 20:07   ` Greg Kroah-Hartman
2017-02-09 20:07     ` Greg Kroah-Hartman
2017-02-09 20:54     ` Michal Hocko
2017-02-09 20:54       ` Michal Hocko
2017-02-10  7:21       ` peter enderborg
2017-02-10  7:21         ` peter enderborg
2017-02-10  7:51         ` Greg Kroah-Hartman
2017-02-10  7:51           ` Greg Kroah-Hartman
2017-02-10  7:59           ` Michal Hocko
2017-02-10  7:59             ` Michal Hocko
2017-02-10  9:05             ` peter enderborg
2017-02-10  9:05               ` peter enderborg
2017-02-10  9:15               ` Michal Hocko
2017-02-10  9:15                 ` Michal Hocko
2017-02-13 15:42                 ` peter enderborg
2017-02-13 15:42                   ` peter enderborg
2017-02-10  9:05           ` peter enderborg
2017-02-10  9:05             ` peter enderborg
2017-02-10 10:34             ` Greg Kroah-Hartman
2017-02-10 10:34               ` Greg Kroah-Hartman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170214165015.GD17335@kroah.com \
    --to=gregkh@linuxfoundation.org \
    --cc=arve@android.com \
    --cc=devel@driverdev.osuosl.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=peter.enderborg@sonymobile.com \
    --cc=riandrews@android.com \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.