diff for duplicates of <20100713101939.2835.90633.sendpatchset@danny.redhat> diff --git a/a/1.txt b/N1/1.txt index 5737ca6..dfbdbf7 100644 --- a/a/1.txt +++ b/N1/1.txt @@ -262,9 +262,3 @@ index fef2434..6bd5765 100644 /* -- 1.7.1.1 - --- -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> diff --git a/a/content_digest b/N1/content_digest index f419dbb..7bafd94 100644 --- a/a/content_digest +++ b/N1/content_digest @@ -279,12 +279,6 @@ " \n" " /*\n" "-- \n" - "1.7.1.1\n" - "\n" - "--\n" - "To unsubscribe, send a message with 'unsubscribe linux-mm' in\n" - "the body to majordomo@kvack.org. For more info on Linux MM,\n" - "see: http://www.linux-mm.org/ .\n" - "Don't email: <a href=mailto:\"dont@kvack.org\"> email@kvack.org </a>" + 1.7.1.1 -7ca4c14b43910b1aaa3977b7c589d2758fe6e21586b4d9de44769ae2975372dc +8489bdf0df9a8e7b1aa881377a0344ae5f34bad5e40c3b79fb88c0540453c5e7
diff --git a/a/1.txt b/N2/1.txt index 5737ca6..8b13789 100644 --- a/a/1.txt +++ b/N2/1.txt @@ -1,270 +1 @@ ->From e8a09c013cf8416ece804ddcbc0d016d2f936e6d Mon Sep 17 00:00:00 2001 -From: Xiaotian Feng <dfeng@redhat.com> -Date: Tue, 13 Jul 2010 11:06:54 +0800 -Subject: [PATCH 15/30] netvm: network reserve infrastructure -Provide the basic infrastructure to reserve and charge/account network memory. - -We provide the following reserve tree: - -1) total network reserve -2) network TX reserve -3) protocol TX pages -4) network RX reserve -5) SKB data reserve - -[1] is used to make all the network reserves a single subtree, for easy -manipulation. - -[2] and [4] are merely for eastetic reasons. - -The TX pages reserve [3] is assumed bounded by it being the upper bound of -memory that can be used for sending pages (not quite true, but good enough) - -The SKB reserve [5] is an aggregate reserve, which is used to charge SKB data -against in the fallback path. - -The consumers for these reserves are sockets marked with: - SOCK_MEMALLOC - -Such sockets are to be used to service the VM (iow. to swap over). They -must be handled kernel side, exposing such a socket to user-space is a BUG. - -Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl> -Signed-off-by: Suresh Jayaraman <sjayaraman@suse.de> -Signed-off-by: Xiaotian Feng <dfeng@redhat.com> ---- - include/net/sock.h | 43 ++++++++++++++++++++- - net/Kconfig | 3 + - net/core/sock.c | 107 ++++++++++++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 152 insertions(+), 1 deletions(-) - -diff --git a/include/net/sock.h b/include/net/sock.h -index 9ddb37b..1de14b6 100644 ---- a/include/net/sock.h -+++ b/include/net/sock.h -@@ -52,6 +52,7 @@ - #include <linux/mm.h> - #include <linux/security.h> - #include <linux/slab.h> -+#include <linux/reserve.h> - - #include <linux/filter.h> - #include <linux/rculist_nulls.h> -@@ -532,6 +533,7 @@ enum sock_flags { - SOCK_RCVTSTAMPNS, /* %SO_TIMESTAMPNS setting */ - SOCK_LOCALROUTE, /* route locally only, %SO_DONTROUTE setting */ - SOCK_QUEUE_SHRUNK, /* write queue has been shrunk recently */ -+ SOCK_MEMALLOC, /* the VM depends on us - make sure we're serviced */ - SOCK_TIMESTAMPING_TX_HARDWARE, /* %SOF_TIMESTAMPING_TX_HARDWARE */ - SOCK_TIMESTAMPING_TX_SOFTWARE, /* %SOF_TIMESTAMPING_TX_SOFTWARE */ - SOCK_TIMESTAMPING_RX_HARDWARE, /* %SOF_TIMESTAMPING_RX_HARDWARE */ -@@ -563,9 +565,48 @@ static inline int sock_flag(struct sock *sk, enum sock_flags flag) - return test_bit(flag, &sk->sk_flags); - } - -+static inline int sk_has_memalloc(struct sock *sk) -+{ -+ return sock_flag(sk, SOCK_MEMALLOC); -+} -+ -+extern struct mem_reserve net_rx_reserve; -+extern struct mem_reserve net_skb_reserve; -+ -+#ifdef CONFIG_NETVM -+/* -+ * Guestimate the per request queue TX upper bound. -+ * -+ * Max packet size is 64k, and we need to reserve that much since the data -+ * might need to bounce it. Double it to be on the safe side. -+ */ -+#define TX_RESERVE_PAGES DIV_ROUND_UP(2*65536, PAGE_SIZE) -+ -+extern int memalloc_socks; -+ -+static inline int sk_memalloc_socks(void) -+{ -+ return memalloc_socks; -+} -+ -+extern int sk_adjust_memalloc(int socks, long tx_reserve_pages); -+extern int sk_set_memalloc(struct sock *sk); -+extern int sk_clear_memalloc(struct sock *sk); -+#else -+static inline int sk_memalloc_socks(void) -+{ -+ return 0; -+} -+ -+static inline int sk_clear_memalloc(struct sock *sk) -+{ -+ return 0; -+} -+#endif -+ - static inline gfp_t sk_allocation(struct sock *sk, gfp_t gfp_mask) - { -- return gfp_mask; -+ return gfp_mask | (sk->sk_allocation & __GFP_MEMALLOC); - } - - static inline void sk_acceptq_removed(struct sock *sk) -diff --git a/net/Kconfig b/net/Kconfig -index 0d68b40..2b61a85 100644 ---- a/net/Kconfig -+++ b/net/Kconfig -@@ -284,4 +284,7 @@ source "net/9p/Kconfig" - source "net/caif/Kconfig" - - -+config NETVM -+ def_bool n -+ - endif # if NET -diff --git a/net/core/sock.c b/net/core/sock.c -index fef2434..6bd5765 100644 ---- a/net/core/sock.c -+++ b/net/core/sock.c -@@ -111,6 +111,7 @@ - #include <linux/init.h> - #include <linux/highmem.h> - #include <linux/user_namespace.h> -+#include <linux/reserve.h> - - #include <asm/uaccess.h> - #include <asm/system.h> -@@ -224,6 +225,105 @@ int net_cls_subsys_id = -1; - EXPORT_SYMBOL_GPL(net_cls_subsys_id); - #endif - -+static struct mem_reserve net_reserve; -+struct mem_reserve net_rx_reserve; -+EXPORT_SYMBOL_GPL(net_rx_reserve); /* modular ipv6 only */ -+struct mem_reserve net_skb_reserve; -+EXPORT_SYMBOL_GPL(net_skb_reserve); /* modular ipv6 only */ -+static struct mem_reserve net_tx_reserve; -+static struct mem_reserve net_tx_pages; -+ -+#ifdef CONFIG_NETVM -+static DEFINE_MUTEX(memalloc_socks_lock); -+int memalloc_socks; -+ -+/** -+ * sk_adjust_memalloc - adjust the global memalloc reserve for critical RX -+ * @socks: number of new %SOCK_MEMALLOC sockets -+ * @tx_resserve_pages: number of pages to (un)reserve for TX -+ * -+ * This function adjusts the memalloc reserve based on system demand. -+ * The RX reserve is a limit, and only added once, not for each socket. -+ * -+ * NOTE: -+ * @tx_reserve_pages is an upper-bound of memory used for TX hence -+ * we need not account the pages like we do for RX pages. -+ */ -+int sk_adjust_memalloc(int socks, long tx_reserve_pages) -+{ -+ int err; -+ -+ mutex_lock(&memalloc_socks_lock); -+ err = mem_reserve_pages_add(&net_tx_pages, tx_reserve_pages); -+ if (err) -+ goto unlock; -+ -+ /* -+ * either socks is positive and we need to check for 0 -> !0 -+ * transition and connect the reserve tree when we observe it. -+ */ -+ if (!memalloc_socks && socks > 0) { -+ err = mem_reserve_connect(&net_reserve, &mem_reserve_root); -+ if (err) { -+ /* -+ * if we failed to connect the tree, undo the tx -+ * reserve so that failure has no side effects. -+ */ -+ mem_reserve_pages_add(&net_tx_pages, -tx_reserve_pages); -+ goto unlock; -+ } -+ } -+ memalloc_socks += socks; -+ /* -+ * or socks is negative and we must observe the !0 -> 0 transition -+ * and disconnect the reserve tree. -+ */ -+ if (!memalloc_socks && socks) -+ mem_reserve_disconnect(&net_reserve); -+ -+unlock: -+ mutex_unlock(&memalloc_socks_lock); -+ -+ return err; -+} -+EXPORT_SYMBOL_GPL(sk_adjust_memalloc); -+ -+/** -+ * sk_set_memalloc - sets %SOCK_MEMALLOC -+ * @sk: socket to set it on -+ * -+ * Set %SOCK_MEMALLOC on a socket and increase the memalloc reserve -+ * accordingly. -+ */ -+int sk_set_memalloc(struct sock *sk) -+{ -+ int set = sock_flag(sk, SOCK_MEMALLOC); -+ -+ if (!set) { -+ int err = sk_adjust_memalloc(1, 0); -+ if (err) -+ return err; -+ -+ sock_set_flag(sk, SOCK_MEMALLOC); -+ sk->sk_allocation |= __GFP_MEMALLOC; -+ } -+ return !set; -+} -+EXPORT_SYMBOL_GPL(sk_set_memalloc); -+ -+int sk_clear_memalloc(struct sock *sk) -+{ -+ int set = sock_flag(sk, SOCK_MEMALLOC); -+ if (set) { -+ sk_adjust_memalloc(-1, 0); -+ sock_reset_flag(sk, SOCK_MEMALLOC); -+ sk->sk_allocation &= ~__GFP_MEMALLOC; -+ } -+ return set; -+} -+EXPORT_SYMBOL_GPL(sk_clear_memalloc); -+#endif -+ - static int sock_set_timeout(long *timeo_p, char __user *optval, int optlen) - { - struct timeval tv; -@@ -1121,6 +1221,7 @@ static void __sk_free(struct sock *sk) - { - struct sk_filter *filter; - -+ sk_clear_memalloc(sk); - if (sk->sk_destruct) - sk->sk_destruct(sk); - -@@ -1300,6 +1401,12 @@ void __init sk_init(void) - sysctl_wmem_max = 131071; - sysctl_rmem_max = 131071; - } -+ -+ mem_reserve_init(&net_reserve, "total network reserve", NULL); -+ mem_reserve_init(&net_rx_reserve, "network RX reserve", &net_reserve); -+ mem_reserve_init(&net_skb_reserve, "SKB data reserve", &net_rx_reserve); -+ mem_reserve_init(&net_tx_reserve, "network TX reserve", &net_reserve); -+ mem_reserve_init(&net_tx_pages, "protocol TX pages", &net_tx_reserve); - } - - /* --- -1.7.1.1 - --- -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> diff --git a/a/content_digest b/N2/content_digest index f419dbb..fa45474 100644 --- a/a/content_digest +++ b/N2/content_digest @@ -16,275 +16,5 @@ " davem@davemloft.net\0" "\00:1\0" "b\0" - ">From e8a09c013cf8416ece804ddcbc0d016d2f936e6d Mon Sep 17 00:00:00 2001\n" - "From: Xiaotian Feng <dfeng@redhat.com>\n" - "Date: Tue, 13 Jul 2010 11:06:54 +0800\n" - "Subject: [PATCH 15/30] netvm: network reserve infrastructure\n" - "\n" - "Provide the basic infrastructure to reserve and charge/account network memory.\n" - "\n" - "We provide the following reserve tree:\n" - "\n" - "1) total network reserve\n" - "2) network TX reserve\n" - "3) protocol TX pages\n" - "4) network RX reserve\n" - "5) SKB data reserve\n" - "\n" - "[1] is used to make all the network reserves a single subtree, for easy\n" - "manipulation.\n" - "\n" - "[2] and [4] are merely for eastetic reasons.\n" - "\n" - "The TX pages reserve [3] is assumed bounded by it being the upper bound of\n" - "memory that can be used for sending pages (not quite true, but good enough)\n" - "\n" - "The SKB reserve [5] is an aggregate reserve, which is used to charge SKB data\n" - "against in the fallback path.\n" - "\n" - "The consumers for these reserves are sockets marked with:\n" - " SOCK_MEMALLOC\n" - "\n" - "Such sockets are to be used to service the VM (iow. to swap over). They\n" - "must be handled kernel side, exposing such a socket to user-space is a BUG.\n" - "\n" - "Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>\n" - "Signed-off-by: Suresh Jayaraman <sjayaraman@suse.de>\n" - "Signed-off-by: Xiaotian Feng <dfeng@redhat.com>\n" - "---\n" - " include/net/sock.h | 43 ++++++++++++++++++++-\n" - " net/Kconfig | 3 +\n" - " net/core/sock.c | 107 ++++++++++++++++++++++++++++++++++++++++++++++++++++\n" - " 3 files changed, 152 insertions(+), 1 deletions(-)\n" - "\n" - "diff --git a/include/net/sock.h b/include/net/sock.h\n" - "index 9ddb37b..1de14b6 100644\n" - "--- a/include/net/sock.h\n" - "+++ b/include/net/sock.h\n" - "@@ -52,6 +52,7 @@\n" - " #include <linux/mm.h>\n" - " #include <linux/security.h>\n" - " #include <linux/slab.h>\n" - "+#include <linux/reserve.h>\n" - " \n" - " #include <linux/filter.h>\n" - " #include <linux/rculist_nulls.h>\n" - "@@ -532,6 +533,7 @@ enum sock_flags {\n" - " \tSOCK_RCVTSTAMPNS, /* %SO_TIMESTAMPNS setting */\n" - " \tSOCK_LOCALROUTE, /* route locally only, %SO_DONTROUTE setting */\n" - " \tSOCK_QUEUE_SHRUNK, /* write queue has been shrunk recently */\n" - "+\tSOCK_MEMALLOC, /* the VM depends on us - make sure we're serviced */\n" - " \tSOCK_TIMESTAMPING_TX_HARDWARE, /* %SOF_TIMESTAMPING_TX_HARDWARE */\n" - " \tSOCK_TIMESTAMPING_TX_SOFTWARE, /* %SOF_TIMESTAMPING_TX_SOFTWARE */\n" - " \tSOCK_TIMESTAMPING_RX_HARDWARE, /* %SOF_TIMESTAMPING_RX_HARDWARE */\n" - "@@ -563,9 +565,48 @@ static inline int sock_flag(struct sock *sk, enum sock_flags flag)\n" - " \treturn test_bit(flag, &sk->sk_flags);\n" - " }\n" - " \n" - "+static inline int sk_has_memalloc(struct sock *sk)\n" - "+{\n" - "+\treturn sock_flag(sk, SOCK_MEMALLOC);\n" - "+}\n" - "+\n" - "+extern struct mem_reserve net_rx_reserve;\n" - "+extern struct mem_reserve net_skb_reserve;\n" - "+\n" - "+#ifdef CONFIG_NETVM\n" - "+/*\n" - "+ * Guestimate the per request queue TX upper bound.\n" - "+ *\n" - "+ * Max packet size is 64k, and we need to reserve that much since the data\n" - "+ * might need to bounce it. Double it to be on the safe side.\n" - "+ */\n" - "+#define TX_RESERVE_PAGES DIV_ROUND_UP(2*65536, PAGE_SIZE)\n" - "+\n" - "+extern int memalloc_socks;\n" - "+\n" - "+static inline int sk_memalloc_socks(void)\n" - "+{\n" - "+\treturn memalloc_socks;\n" - "+}\n" - "+\n" - "+extern int sk_adjust_memalloc(int socks, long tx_reserve_pages);\n" - "+extern int sk_set_memalloc(struct sock *sk);\n" - "+extern int sk_clear_memalloc(struct sock *sk);\n" - "+#else\n" - "+static inline int sk_memalloc_socks(void)\n" - "+{\n" - "+\treturn 0;\n" - "+}\n" - "+\n" - "+static inline int sk_clear_memalloc(struct sock *sk)\n" - "+{\n" - "+\treturn 0;\n" - "+}\n" - "+#endif\n" - "+\n" - " static inline gfp_t sk_allocation(struct sock *sk, gfp_t gfp_mask)\n" - " {\n" - "-\treturn gfp_mask;\n" - "+\treturn gfp_mask | (sk->sk_allocation & __GFP_MEMALLOC);\n" - " }\n" - " \n" - " static inline void sk_acceptq_removed(struct sock *sk)\n" - "diff --git a/net/Kconfig b/net/Kconfig\n" - "index 0d68b40..2b61a85 100644\n" - "--- a/net/Kconfig\n" - "+++ b/net/Kconfig\n" - "@@ -284,4 +284,7 @@ source \"net/9p/Kconfig\"\n" - " source \"net/caif/Kconfig\"\n" - " \n" - " \n" - "+config NETVM\n" - "+\tdef_bool n\n" - "+\n" - " endif # if NET\n" - "diff --git a/net/core/sock.c b/net/core/sock.c\n" - "index fef2434..6bd5765 100644\n" - "--- a/net/core/sock.c\n" - "+++ b/net/core/sock.c\n" - "@@ -111,6 +111,7 @@\n" - " #include <linux/init.h>\n" - " #include <linux/highmem.h>\n" - " #include <linux/user_namespace.h>\n" - "+#include <linux/reserve.h>\n" - " \n" - " #include <asm/uaccess.h>\n" - " #include <asm/system.h>\n" - "@@ -224,6 +225,105 @@ int net_cls_subsys_id = -1;\n" - " EXPORT_SYMBOL_GPL(net_cls_subsys_id);\n" - " #endif\n" - " \n" - "+static struct mem_reserve net_reserve;\n" - "+struct mem_reserve net_rx_reserve;\n" - "+EXPORT_SYMBOL_GPL(net_rx_reserve); /* modular ipv6 only */\n" - "+struct mem_reserve net_skb_reserve;\n" - "+EXPORT_SYMBOL_GPL(net_skb_reserve); /* modular ipv6 only */\n" - "+static struct mem_reserve net_tx_reserve;\n" - "+static struct mem_reserve net_tx_pages;\n" - "+\n" - "+#ifdef CONFIG_NETVM\n" - "+static DEFINE_MUTEX(memalloc_socks_lock);\n" - "+int memalloc_socks;\n" - "+\n" - "+/**\n" - "+ *\tsk_adjust_memalloc - adjust the global memalloc reserve for critical RX\n" - "+ *\t@socks: number of new %SOCK_MEMALLOC sockets\n" - "+ *\t@tx_resserve_pages: number of pages to (un)reserve for TX\n" - "+ *\n" - "+ *\tThis function adjusts the memalloc reserve based on system demand.\n" - "+ *\tThe RX reserve is a limit, and only added once, not for each socket.\n" - "+ *\n" - "+ *\tNOTE:\n" - "+ *\t @tx_reserve_pages is an upper-bound of memory used for TX hence\n" - "+ *\t we need not account the pages like we do for RX pages.\n" - "+ */\n" - "+int sk_adjust_memalloc(int socks, long tx_reserve_pages)\n" - "+{\n" - "+\tint err;\n" - "+\n" - "+\tmutex_lock(&memalloc_socks_lock);\n" - "+\terr = mem_reserve_pages_add(&net_tx_pages, tx_reserve_pages);\n" - "+\tif (err)\n" - "+\t\tgoto unlock;\n" - "+\n" - "+\t/*\n" - "+\t * either socks is positive and we need to check for 0 -> !0\n" - "+\t * transition and connect the reserve tree when we observe it.\n" - "+\t */\n" - "+\tif (!memalloc_socks && socks > 0) {\n" - "+\t\terr = mem_reserve_connect(&net_reserve, &mem_reserve_root);\n" - "+\t\tif (err) {\n" - "+\t\t\t/*\n" - "+\t\t\t * if we failed to connect the tree, undo the tx\n" - "+\t\t\t * reserve so that failure has no side effects.\n" - "+\t\t\t */\n" - "+\t\t\tmem_reserve_pages_add(&net_tx_pages, -tx_reserve_pages);\n" - "+\t\t\tgoto unlock;\n" - "+\t\t}\n" - "+\t}\n" - "+\tmemalloc_socks += socks;\n" - "+\t/*\n" - "+\t * or socks is negative and we must observe the !0 -> 0 transition\n" - "+\t * and disconnect the reserve tree.\n" - "+\t */\n" - "+\tif (!memalloc_socks && socks)\n" - "+\t\tmem_reserve_disconnect(&net_reserve);\n" - "+\n" - "+unlock:\n" - "+\tmutex_unlock(&memalloc_socks_lock);\n" - "+\n" - "+\treturn err;\n" - "+}\n" - "+EXPORT_SYMBOL_GPL(sk_adjust_memalloc);\n" - "+\n" - "+/**\n" - "+ *\tsk_set_memalloc - sets %SOCK_MEMALLOC\n" - "+ *\t@sk: socket to set it on\n" - "+ *\n" - "+ *\tSet %SOCK_MEMALLOC on a socket and increase the memalloc reserve\n" - "+ *\taccordingly.\n" - "+ */\n" - "+int sk_set_memalloc(struct sock *sk)\n" - "+{\n" - "+\tint set = sock_flag(sk, SOCK_MEMALLOC);\n" - "+\n" - "+\tif (!set) {\n" - "+\t\tint err = sk_adjust_memalloc(1, 0);\n" - "+\t\tif (err)\n" - "+\t\t\treturn err;\n" - "+\n" - "+\t\tsock_set_flag(sk, SOCK_MEMALLOC);\n" - "+\t\tsk->sk_allocation |= __GFP_MEMALLOC;\n" - "+\t}\n" - "+\treturn !set;\n" - "+}\n" - "+EXPORT_SYMBOL_GPL(sk_set_memalloc);\n" - "+\n" - "+int sk_clear_memalloc(struct sock *sk)\n" - "+{\n" - "+\tint set = sock_flag(sk, SOCK_MEMALLOC);\n" - "+\tif (set) {\n" - "+\t\tsk_adjust_memalloc(-1, 0);\n" - "+\t\tsock_reset_flag(sk, SOCK_MEMALLOC);\n" - "+\t\tsk->sk_allocation &= ~__GFP_MEMALLOC;\n" - "+\t}\n" - "+\treturn set;\n" - "+}\n" - "+EXPORT_SYMBOL_GPL(sk_clear_memalloc);\n" - "+#endif\n" - "+\n" - " static int sock_set_timeout(long *timeo_p, char __user *optval, int optlen)\n" - " {\n" - " \tstruct timeval tv;\n" - "@@ -1121,6 +1221,7 @@ static void __sk_free(struct sock *sk)\n" - " {\n" - " \tstruct sk_filter *filter;\n" - " \n" - "+\tsk_clear_memalloc(sk);\n" - " \tif (sk->sk_destruct)\n" - " \t\tsk->sk_destruct(sk);\n" - " \n" - "@@ -1300,6 +1401,12 @@ void __init sk_init(void)\n" - " \t\tsysctl_wmem_max = 131071;\n" - " \t\tsysctl_rmem_max = 131071;\n" - " \t}\n" - "+\n" - "+\tmem_reserve_init(&net_reserve, \"total network reserve\", NULL);\n" - "+\tmem_reserve_init(&net_rx_reserve, \"network RX reserve\", &net_reserve);\n" - "+\tmem_reserve_init(&net_skb_reserve, \"SKB data reserve\", &net_rx_reserve);\n" - "+\tmem_reserve_init(&net_tx_reserve, \"network TX reserve\", &net_reserve);\n" - "+\tmem_reserve_init(&net_tx_pages, \"protocol TX pages\", &net_tx_reserve);\n" - " }\n" - " \n" - " /*\n" - "-- \n" - "1.7.1.1\n" - "\n" - "--\n" - "To unsubscribe, send a message with 'unsubscribe linux-mm' in\n" - "the body to majordomo@kvack.org. For more info on Linux MM,\n" - "see: http://www.linux-mm.org/ .\n" - "Don't email: <a href=mailto:\"dont@kvack.org\"> email@kvack.org </a>" -7ca4c14b43910b1aaa3977b7c589d2758fe6e21586b4d9de44769ae2975372dc +e83a52bc41f1b6d6f71d29d4c56c600460ccf78276f87411f2e02c7a85aae192
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.