mm-commits.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Andrew Morton <akpm@linux-foundation.org>
To: akpm@linux-foundation.org, augusto.duraes33@gmail.com,
	brendanhiggins@google.com, davidgow@google.com,
	dlatypov@google.com, ferreiraenzoa@gmail.com,
	geert@linux-m68k.org, isabbasso@riseup.net, linux-mm@kvack.org,
	lkp@intel.com, mm-commits@vger.kernel.org,
	rodrigosiqueiramelo@gmail.com, skhan@linuxfoundation.org,
	torvalds@linux-foundation.org
Subject: [patch 29/55] test_hash.c: refactor into kunit
Date: Wed, 19 Jan 2022 18:09:15 -0800	[thread overview]
Message-ID: <20220120020915.Uov420pbR%akpm@linux-foundation.org> (raw)
In-Reply-To: <20220119180714.9e187ce100e4510de3cd9f7d@linux-foundation.org>

From: Isabella Basso <isabbasso@riseup.net>
Subject: test_hash.c: refactor into kunit

Use KUnit framework to make tests more easily integrable with CIs.  Even
though these tests are not yet properly written as unit tests this change
should help in debugging.

Also remove kernel messages (i.e.  through pr_info) as KUnit handles all
debugging output and let it handle module init and exit details.

Link: https://lkml.kernel.org/r/20211208183711.390454-6-isabbasso@riseup.net
Reviewed-by: David Gow <davidgow@google.com>
Reported-by: kernel test robot <lkp@intel.com>
Tested-by: David Gow <davidgow@google.com>
Co-developed-by: Augusto Durães Camargo <augusto.duraes33@gmail.com>
Signed-off-by: Augusto Durães Camargo <augusto.duraes33@gmail.com>
Co-developed-by: Enzo Ferreira <ferreiraenzoa@gmail.com>
Signed-off-by: Enzo Ferreira <ferreiraenzoa@gmail.com>
Signed-off-by: Isabella Basso <isabbasso@riseup.net>
Cc: Brendan Higgins <brendanhiggins@google.com>
Cc: Daniel Latypov <dlatypov@google.com>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: Rodrigo Siqueira <rodrigosiqueiramelo@gmail.com>
Cc: Shuah Khan <skhan@linuxfoundation.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---

 lib/Kconfig.debug |   28 ++++--
 lib/Makefile      |    2 
 lib/test_hash.c   |  194 +++++++++++++-------------------------------
 3 files changed, 81 insertions(+), 143 deletions(-)

--- a/lib/Kconfig.debug~test_hashc-refactor-into-kunit
+++ a/lib/Kconfig.debug
@@ -2207,15 +2207,6 @@ config TEST_RHASHTABLE
 
 	  If unsure, say N.
 
-config TEST_HASH
-	tristate "Perform selftest on hash functions"
-	help
-	  Enable this option to test the kernel's integer (<linux/hash.h>), and
-	  string (<linux/stringhash.h>) hash functions on boot (or module load).
-
-	  This is intended to help people writing architecture-specific
-	  optimized versions.  If unsure, say N.
-
 config TEST_SIPHASH
 	tristate "Perform selftest on siphash functions"
 	help
@@ -2364,6 +2355,25 @@ config BITFIELD_KUNIT
 
 	  If unsure, say N.
 
+config HASH_KUNIT_TEST
+	tristate "KUnit Test for integer hash functions" if !KUNIT_ALL_TESTS
+	depends on KUNIT
+	default KUNIT_ALL_TESTS
+	help
+	  Enable this option to test the kernel's string (<linux/stringhash.h>), and
+	  integer (<linux/hash.h>) hash functions on boot.
+
+	  KUnit tests run during boot and output the results to the debug log
+	  in TAP format (https://testanything.org/). Only useful for kernel devs
+	  running the KUnit test harness, and not intended for inclusion into a
+	  production build.
+
+	  For more information on KUnit and unit tests in general please refer
+	  to the KUnit documentation in Documentation/dev-tools/kunit/.
+
+	  This is intended to help people writing architecture-specific
+	  optimized versions. If unsure, say N.
+
 config RESOURCE_KUNIT_TEST
 	tristate "KUnit test for resource API"
 	depends on KUNIT
--- a/lib/Makefile~test_hashc-refactor-into-kunit
+++ a/lib/Makefile
@@ -62,7 +62,7 @@ obj-$(CONFIG_TEST_BITOPS) += test_bitops
 CFLAGS_test_bitops.o += -Werror
 obj-$(CONFIG_TEST_SYSCTL) += test_sysctl.o
 obj-$(CONFIG_TEST_SIPHASH) += test_siphash.o
-obj-$(CONFIG_TEST_HASH) += test_hash.o
+obj-$(CONFIG_HASH_KUNIT_TEST) += test_hash.o
 obj-$(CONFIG_TEST_IDA) += test_ida.o
 obj-$(CONFIG_KASAN_KUNIT_TEST) += test_kasan.o
 CFLAGS_test_kasan.o += -fno-builtin
--- a/lib/test_hash.c~test_hashc-refactor-into-kunit
+++ a/lib/test_hash.c
@@ -14,17 +14,15 @@
  * and hash_64().
  */
 
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt "\n"
-
 #include <linux/compiler.h>
 #include <linux/types.h>
 #include <linux/module.h>
 #include <linux/hash.h>
 #include <linux/stringhash.h>
-#include <linux/printk.h>
+#include <kunit/test.h>
 
 /* 32-bit XORSHIFT generator.  Seed must not be zero. */
-static u32 __init __attribute_const__
+static u32 __attribute_const__
 xorshift(u32 seed)
 {
 	seed ^= seed << 13;
@@ -34,7 +32,7 @@ xorshift(u32 seed)
 }
 
 /* Given a non-zero x, returns a non-zero byte. */
-static u8 __init __attribute_const__
+static u8 __attribute_const__
 mod255(u32 x)
 {
 	x = (x & 0xffff) + (x >> 16);	/* 1 <= x <= 0x1fffe */
@@ -45,8 +43,7 @@ mod255(u32 x)
 }
 
 /* Fill the buffer with non-zero bytes. */
-static void __init
-fill_buf(char *buf, size_t len, u32 seed)
+static void fill_buf(char *buf, size_t len, u32 seed)
 {
 	size_t i;
 
@@ -71,40 +68,32 @@ struct test_hash_params {
 };
 
 #ifdef HAVE_ARCH__HASH_32
-static bool __init
-test_int__hash_32(struct test_hash_params *params)
+static void
+test_int__hash_32(struct kunit *test, struct test_hash_params *params)
 {
 	params->hash_or[1][0] |= params->h2 = __hash_32_generic(params->h0);
 #if HAVE_ARCH__HASH_32 == 1
-	if (params->h1 != params->h2) {
-		pr_err("__hash_32(%#x) = %#x != __hash_32_generic() = %#x",
-		       params->h0, params->h1, params->h2);
-		return false;
-	}
+	KUNIT_EXPECT_EQ_MSG(test, params->h1, params->h2,
+			    "__hash_32(%#x) = %#x != __hash_32_generic() = %#x",
+			    params->h0, params->h1, params->h2);
 #endif
-	return true;
 }
 #endif
 
 #ifdef HAVE_ARCH_HASH_64
-static bool __init
-test_int_hash_64(struct test_hash_params *params, u32 const *m, int *k)
+static void
+test_int_hash_64(struct kunit *test, struct test_hash_params *params, u32 const *m, int *k)
 {
 	params->h2 = hash_64_generic(*params->h64, *k);
 #if HAVE_ARCH_HASH_64 == 1
-	if (params->h1 != params->h2) {
-		pr_err("hash_64(%#llx, %d) = %#x != hash_64_generic() = %#x",
-		       *params->h64, *k, params->h1, params->h2);
-		return false;
-	}
+	KUNIT_EXPECT_EQ_MSG(test, params->h1, params->h2,
+			    "hash_64(%#llx, %d) = %#x != hash_64_generic() = %#x",
+			    *params->h64, *k, params->h1, params->h2);
 #else
-	if (params->h2 > *m) {
-		pr_err("hash_64_generic(%#llx, %d) = %#x > %#x",
-		       *params->h64, *k, params->h1, *m);
-		return false;
-	}
+	KUNIT_EXPECT_LE_MSG(test, params->h1, params->h2,
+			    "hash_64_generic(%#llx, %d) = %#x > %#x",
+			    *params->h64, *k, params->h1, *m);
 #endif
-	return true;
 }
 #endif
 
@@ -117,8 +106,8 @@ test_int_hash_64(struct test_hash_params
  * inline, the code being tested is actually in the module, and you can
  * recompile and re-test the module without rebooting.
  */
-static bool __init
-test_int_hash(unsigned long long h64, u32 hash_or[2][33])
+static void
+test_int_hash(struct kunit *test, unsigned long long h64, u32 hash_or[2][33])
 {
 	int k;
 	struct test_hash_params params = { &h64, (u32)h64, 0, 0, hash_or };
@@ -126,8 +115,7 @@ test_int_hash(unsigned long long h64, u3
 	/* Test __hash32 */
 	hash_or[0][0] |= params.h1 = __hash_32(params.h0);
 #ifdef HAVE_ARCH__HASH_32
-	if (!test_int__hash_32(&params))
-		return false;
+	test_int__hash_32(test, &params);
 #endif
 
 	/* Test k = 1..32 bits */
@@ -136,29 +124,24 @@ test_int_hash(unsigned long long h64, u3
 
 		/* Test hash_32 */
 		hash_or[0][k] |= params.h1 = hash_32(params.h0, k);
-		if (params.h1 > m) {
-			pr_err("hash_32(%#x, %d) = %#x > %#x", params.h0, k, params.h1, m);
-			return false;
-		}
+		KUNIT_EXPECT_LE_MSG(test, params.h1, m,
+				    "hash_32(%#x, %d) = %#x > %#x",
+				    params.h0, k, params.h1, m);
 
 		/* Test hash_64 */
 		hash_or[1][k] |= params.h1 = hash_64(h64, k);
-		if (params.h1 > m) {
-			pr_err("hash_64(%#llx, %d) = %#x > %#x", h64, k, params.h1, m);
-			return false;
-		}
+		KUNIT_EXPECT_LE_MSG(test, params.h1, m,
+				    "hash_64(%#llx, %d) = %#x > %#x",
+				    h64, k, params.h1, m);
 #ifdef HAVE_ARCH_HASH_64
-		if (!test_int_hash_64(&params, &m, &k))
-			return false;
+		test_int_hash_64(test, &params, &m, &k);
 #endif
 	}
-
-	return true;
 }
 
 #define SIZE 256	/* Run time is cubic in SIZE */
 
-static int __init test_string_or(void)
+static void test_string_or(struct kunit *test)
 {
 	char buf[SIZE+1];
 	u32 string_or = 0;
@@ -178,20 +161,15 @@ static int __init test_string_or(void)
 	} /* j */
 
 	/* The OR of all the hash values should cover all the bits */
-	if (~string_or) {
-		pr_err("OR of all string hash results = %#x != %#x",
-		       string_or, -1u);
-		return -EINVAL;
-	}
-
-	return 0;
+	KUNIT_EXPECT_EQ_MSG(test, string_or, -1u,
+			    "OR of all string hash results = %#x != %#x",
+			    string_or, -1u);
 }
 
-static int __init test_hash_or(void)
+static void test_hash_or(struct kunit *test)
 {
 	char buf[SIZE+1];
 	u32 hash_or[2][33] = { { 0, } };
-	unsigned tests = 0;
 	unsigned long long h64 = 0;
 	int i, j;
 
@@ -206,39 +184,27 @@ static int __init test_hash_or(void)
 			u32 h0 = full_name_hash(buf+i, buf+i, j-i);
 
 			/* Check that hashlen_string gets the length right */
-			if (hashlen_len(hashlen) != j-i) {
-				pr_err("hashlen_string(%d..%d) returned length"
-					" %u, expected %d",
-					i, j, hashlen_len(hashlen), j-i);
-				return -EINVAL;
-			}
+			KUNIT_EXPECT_EQ_MSG(test, hashlen_len(hashlen), j-i,
+					    "hashlen_string(%d..%d) returned length %u, expected %d",
+					    i, j, hashlen_len(hashlen), j-i);
 			/* Check that the hashes match */
-			if (hashlen_hash(hashlen) != h0) {
-				pr_err("hashlen_string(%d..%d) = %08x != "
-					"full_name_hash() = %08x",
-					i, j, hashlen_hash(hashlen), h0);
-				return -EINVAL;
-			}
+			KUNIT_EXPECT_EQ_MSG(test, hashlen_hash(hashlen), h0,
+					    "hashlen_string(%d..%d) = %08x != full_name_hash() = %08x",
+					    i, j, hashlen_hash(hashlen), h0);
 
 			h64 = h64 << 32 | h0;	/* For use with hash_64 */
-			if (!test_int_hash(h64, hash_or))
-				return -EINVAL;
-			tests++;
+			test_int_hash(test, h64, hash_or);
 		} /* i */
 	} /* j */
 
-	if (~hash_or[0][0]) {
-		pr_err("OR of all __hash_32 results = %#x != %#x",
-			hash_or[0][0], -1u);
-		return -EINVAL;
-	}
+	KUNIT_EXPECT_EQ_MSG(test, hash_or[0][0], -1u,
+			    "OR of all __hash_32 results = %#x != %#x",
+			    hash_or[0][0], -1u);
 #ifdef HAVE_ARCH__HASH_32
 #if HAVE_ARCH__HASH_32 != 1	/* Test is pointless if results match */
-	if (~hash_or[1][0]) {
-		pr_err("OR of all __hash_32_generic results = %#x != %#x",
-			hash_or[1][0], -1u);
-		return -EINVAL;
-	}
+	KUNIT_EXPECT_EQ_MSG(test, hash_or[1][0], -1u,
+			    "OR of all __hash_32_generic results = %#x != %#x",
+			    hash_or[1][0], -1u);
 #endif
 #endif
 
@@ -246,65 +212,27 @@ static int __init test_hash_or(void)
 	for (i = 1; i <= 32; i++) {
 		u32 const m = ((u32)2 << (i-1)) - 1;	/* Low i bits set */
 
-		if (hash_or[0][i] != m) {
-			pr_err("OR of all hash_32(%d) results = %#x "
-				"(%#x expected)", i, hash_or[0][i], m);
-			return -EINVAL;
-		}
-		if (hash_or[1][i] != m) {
-			pr_err("OR of all hash_64(%d) results = %#x "
-				"(%#x expected)", i, hash_or[1][i], m);
-			return -EINVAL;
-		}
+		KUNIT_EXPECT_EQ_MSG(test, hash_or[0][i], m,
+				    "OR of all hash_32(%d) results = %#x (%#x expected)",
+				    i, hash_or[0][i], m);
+		KUNIT_EXPECT_EQ_MSG(test, hash_or[1][i], m,
+				    "OR of all hash_64(%d) results = %#x (%#x expected)",
+				    i, hash_or[1][i], m);
 	}
-
-	pr_notice("%u tests passed.", tests);
-
-	return 0;
 }
 
-static void __init notice_skipped_tests(void)
-{
-	/* Issue notices about skipped tests. */
-#ifdef HAVE_ARCH__HASH_32
-#if HAVE_ARCH__HASH_32 != 1
-	pr_info("__hash_32() is arch-specific; not compared to generic.");
-#endif
-#else
-	pr_info("__hash_32() has no arch implementation to test.");
-#endif
-#ifdef HAVE_ARCH_HASH_64
-#if HAVE_ARCH_HASH_64 != 1
-	pr_info("hash_64() is arch-specific; not compared to generic.");
-#endif
-#else
-	pr_info("hash_64() has no arch implementation to test.");
-#endif
-}
-
-static int __init
-test_hash_init(void)
-{
-	int ret;
-
-	ret = test_string_or();
-	if (ret < 0)
-		return ret;
-
-	ret = test_hash_or();
-	if (ret < 0)
-		return ret;
-
-	notice_skipped_tests();
+static struct kunit_case hash_test_cases[] __refdata = {
+	KUNIT_CASE(test_string_or),
+	KUNIT_CASE(test_hash_or),
+	{}
+};
 
-	return ret;
-}
+static struct kunit_suite hash_test_suite = {
+	.name = "hash",
+	.test_cases = hash_test_cases,
+};
 
-static void __exit test_hash_exit(void)
-{
-}
 
-module_init(test_hash_init);	/* Does everything */
-module_exit(test_hash_exit);	/* Does nothing */
+kunit_test_suite(hash_test_suite);
 
 MODULE_LICENSE("GPL");
_

  parent reply	other threads:[~2022-01-20  2:09 UTC|newest]

Thread overview: 56+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-01-20  2:07 incoming Andrew Morton
2022-01-20  2:07 ` [patch 01/55] mm: percpu: generalize percpu related config Andrew Morton
2022-01-20  2:07 ` [patch 02/55] mm: percpu: add pcpu_fc_cpu_to_node_fn_t typedef Andrew Morton
2022-01-20  2:07 ` [patch 03/55] mm: percpu: add generic pcpu_fc_alloc/free funciton Andrew Morton
2022-01-20  2:07 ` [patch 04/55] mm: percpu: add generic pcpu_populate_pte() function Andrew Morton
2022-01-20  2:07 ` [patch 05/55] proc/vmcore: don't fake reading zeroes on surprise vmcore_cb unregistration Andrew Morton
2022-01-20  2:08 ` [patch 06/55] proc: make the proc_create[_data]() stubs static inlines Andrew Morton
2022-01-20  2:08 ` [patch 07/55] proc: convert the return type of proc_fd_access_allowed() to be boolean Andrew Morton
2022-01-20  2:08 ` [patch 08/55] sysctl: fix duplicate path separator in printed entries Andrew Morton
2022-01-20  2:08 ` [patch 09/55] sysctl: remove redundant ret assignment Andrew Morton
2022-01-20  2:08 ` [patch 10/55] include/linux/unaligned: replace kernel.h with the necessary inclusions Andrew Morton
2022-01-20  2:08 ` [patch 11/55] kernel.h: include a note to discourage people from including it in headers Andrew Morton
2022-01-20  2:08 ` [patch 12/55] fs/exec: replace strlcpy with strscpy_pad in __set_task_comm Andrew Morton
2022-01-20  2:08 ` [patch 13/55] fs/exec: replace strncpy with strscpy_pad in __get_task_comm Andrew Morton
2022-01-20  2:08 ` [patch 14/55] drivers/infiniband: replace open-coded string copy with get_task_comm Andrew Morton
2022-01-20  2:08 ` [patch 15/55] fs/binfmt_elf: " Andrew Morton
2022-01-20  2:08 ` [patch 16/55] samples/bpf/test_overhead_kprobe_kern: replace bpf_probe_read_kernel with bpf_probe_read_kernel_str to get task comm Andrew Morton
2022-01-20  2:08 ` [patch 17/55] tools/bpf/bpftool/skeleton: " Andrew Morton
2022-01-20  2:08 ` [patch 18/55] tools/testing/selftests/bpf: replace open-coded 16 with TASK_COMM_LEN Andrew Morton
2022-01-20  2:08 ` [patch 19/55] kthread: dynamically allocate memory to store kthread's full name Andrew Morton
2022-01-20  2:08 ` [patch 20/55] kernel/sys.c: only take tasklist_lock for get/setpriority(PRIO_PGRP) Andrew Morton
2022-01-20  2:08 ` [patch 21/55] get_maintainer: don't remind about no git repo when --nogit is used Andrew Morton
2022-01-20  2:08 ` [patch 22/55] kstrtox: uninline everything Andrew Morton
2022-01-20  2:08 ` [patch 23/55] list: introduce list_is_head() helper and re-use it in list.h Andrew Morton
2022-01-20  2:08 ` [patch 24/55] lib/list_debug.c: print more list debugging context in __list_del_entry_valid() Andrew Morton
2022-01-20  2:09 ` [patch 25/55] hash.h: remove unused define directive Andrew Morton
2022-01-20  2:09 ` [patch 26/55] test_hash.c: split test_int_hash into arch-specific functions Andrew Morton
2022-01-20  2:09 ` [patch 27/55] test_hash.c: split test_hash_init Andrew Morton
2022-01-20  2:09 ` [patch 28/55] lib/Kconfig.debug: properly split hash test kernel entries Andrew Morton
2022-01-20  2:09 ` Andrew Morton [this message]
2022-01-20  2:09 ` [patch 30/55] kunit: replace kernel.h with the necessary inclusions Andrew Morton
2022-01-20  2:09 ` [patch 31/55] uuid: discourage people from using UAPI header in new code Andrew Morton
2022-01-20  2:09 ` [patch 32/55] uuid: remove licence boilerplate text from the header Andrew Morton
2022-01-20  2:09 ` [patch 33/55] lib/test_meminit: destroy cache in kmem_cache_alloc_bulk() test Andrew Morton
2022-01-20  2:09 ` [patch 34/55] checkpatch: relax regexp for COMMIT_LOG_LONG_LINE Andrew Morton
2022-01-20  2:09 ` [patch 35/55] checkpatch: improve Kconfig help test Andrew Morton
2022-01-20  2:09 ` [patch 36/55] const_structs.checkpatch: add frequently used ops structs Andrew Morton
2022-01-20  2:09 ` [patch 37/55] fs/binfmt_elf: use PT_LOAD p_align values for static PIE Andrew Morton
2022-01-20  2:09 ` [patch 38/55] nilfs2: remove redundant pointer sbufs Andrew Morton
2022-01-20  2:09 ` [patch 39/55] hfsplus: use struct_group_attr() for memcpy() region Andrew Morton
2022-01-20  2:09 ` [patch 40/55] FAT: use io_schedule_timeout() instead of congestion_wait() Andrew Morton
2022-01-20  2:09 ` [patch 41/55] fs/adfs: remove unneeded variable make code cleaner Andrew Morton
2022-01-20  2:09 ` [patch 42/55] panic: use error_report_end tracepoint on warnings Andrew Morton
2022-01-20  2:09 ` [patch 43/55] panic: remove oops_id Andrew Morton
2022-01-20  2:10 ` [patch 44/55] delayacct: support swapin delay accounting for swapping without blkio Andrew Morton
2022-01-20  2:10 ` [patch 45/55] delayacct: fix incomplete disable operation when switch enable to disable Andrew Morton
2022-01-20  2:10 ` [patch 46/55] delayacct: cleanup flags in struct task_delay_info and functions use it Andrew Morton
2022-01-20  2:10 ` [patch 47/55] Documentation/accounting/delay-accounting.rst: add thrashing page cache and direct compact Andrew Morton
2022-01-20  2:10 ` [patch 48/55] delayacct: track delays from memory compact Andrew Morton
2022-01-20  2:10 ` [patch 49/55] configs: introduce debug.config for CI-like setup Andrew Morton
2022-01-20  2:10 ` [patch 50/55] arch/Kconfig: split PAGE_SIZE_LESS_THAN_256KB from PAGE_SIZE_LESS_THAN_64KB Andrew Morton
2022-01-20  2:10 ` [patch 51/55] btrfs: use generic Kconfig option for 256kB page size limit Andrew Morton
2022-01-20  2:10 ` [patch 52/55] lib/Kconfig.debug: make TEST_KMOD depend on PAGE_SIZE_LESS_THAN_256KB Andrew Morton
2022-01-20  2:10 ` [patch 53/55] kcov: fix generic Kconfig dependencies if ARCH_WANTS_NO_INSTR Andrew Morton
2022-01-20  2:10 ` [patch 54/55] ubsan: remove CONFIG_UBSAN_OBJECT_SIZE Andrew Morton
2022-01-20  2:10 ` [patch 55/55] lib: remove redundant assignment to variable ret Andrew Morton

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=20220120020915.Uov420pbR%akpm@linux-foundation.org \
    --to=akpm@linux-foundation.org \
    --cc=augusto.duraes33@gmail.com \
    --cc=brendanhiggins@google.com \
    --cc=davidgow@google.com \
    --cc=dlatypov@google.com \
    --cc=ferreiraenzoa@gmail.com \
    --cc=geert@linux-m68k.org \
    --cc=isabbasso@riseup.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=lkp@intel.com \
    --cc=mm-commits@vger.kernel.org \
    --cc=rodrigosiqueiramelo@gmail.com \
    --cc=skhan@linuxfoundation.org \
    --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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).