* [PATCH] x86/mm/dump_pagetables: Change to use DEFINE_SHOW_ATTRIBUTE macro
@ 2018-11-19 15:43 Yangtao Li
2018-11-19 17:06 ` Dave Hansen
2018-12-18 12:09 ` [tip:x86/mm] x86/mm/dump_pagetables: Use DEFINE_SHOW_ATTRIBUTE() tip-bot for Yangtao Li
0 siblings, 2 replies; 9+ messages in thread
From: Yangtao Li @ 2018-11-19 15:43 UTC (permalink / raw)
To: keescook, dave.hansen, luto, peterz, tglx, mingo, bp, hpa
Cc: x86, linux-kernel, Yangtao Li
Use DEFINE_SHOW_ATTRIBUTE macro to simplify the code.
Signed-off-by: Yangtao Li <tiny.windzz@gmail.com>
---
arch/x86/mm/debug_pagetables.c | 58 ++++------------------------------
1 file changed, 7 insertions(+), 51 deletions(-)
diff --git a/arch/x86/mm/debug_pagetables.c b/arch/x86/mm/debug_pagetables.c
index 225fe2f0bfec..cd84f067e41d 100644
--- a/arch/x86/mm/debug_pagetables.c
+++ b/arch/x86/mm/debug_pagetables.c
@@ -10,20 +10,9 @@ static int ptdump_show(struct seq_file *m, void *v)
return 0;
}
-static int ptdump_open(struct inode *inode, struct file *filp)
-{
- return single_open(filp, ptdump_show, NULL);
-}
-
-static const struct file_operations ptdump_fops = {
- .owner = THIS_MODULE,
- .open = ptdump_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
+DEFINE_SHOW_ATTRIBUTE(ptdump);
-static int ptdump_show_curknl(struct seq_file *m, void *v)
+static int ptdump_curknl_show(struct seq_file *m, void *v)
{
if (current->mm->pgd) {
down_read(¤t->mm->mmap_sem);
@@ -33,23 +22,12 @@ static int ptdump_show_curknl(struct seq_file *m, void *v)
return 0;
}
-static int ptdump_open_curknl(struct inode *inode, struct file *filp)
-{
- return single_open(filp, ptdump_show_curknl, NULL);
-}
-
-static const struct file_operations ptdump_curknl_fops = {
- .owner = THIS_MODULE,
- .open = ptdump_open_curknl,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
+DEFINE_SHOW_ATTRIBUTE(ptdump_curknl);
#ifdef CONFIG_PAGE_TABLE_ISOLATION
static struct dentry *pe_curusr;
-static int ptdump_show_curusr(struct seq_file *m, void *v)
+static int ptdump_curusr_show(struct seq_file *m, void *v)
{
if (current->mm->pgd) {
down_read(¤t->mm->mmap_sem);
@@ -59,42 +37,20 @@ static int ptdump_show_curusr(struct seq_file *m, void *v)
return 0;
}
-static int ptdump_open_curusr(struct inode *inode, struct file *filp)
-{
- return single_open(filp, ptdump_show_curusr, NULL);
-}
-
-static const struct file_operations ptdump_curusr_fops = {
- .owner = THIS_MODULE,
- .open = ptdump_open_curusr,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
+DEFINE_SHOW_ATTRIBUTE(ptdump_curusr);
#endif
#if defined(CONFIG_EFI) && defined(CONFIG_X86_64)
static struct dentry *pe_efi;
-static int ptdump_show_efi(struct seq_file *m, void *v)
+static int ptdump_efi_show(struct seq_file *m, void *v)
{
if (efi_mm.pgd)
ptdump_walk_pgd_level_debugfs(m, efi_mm.pgd, false);
return 0;
}
-static int ptdump_open_efi(struct inode *inode, struct file *filp)
-{
- return single_open(filp, ptdump_show_efi, NULL);
-}
-
-static const struct file_operations ptdump_efi_fops = {
- .owner = THIS_MODULE,
- .open = ptdump_open_efi,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
+DEFINE_SHOW_ATTRIBUTE(ptdump_efi);
#endif
static struct dentry *dir, *pe_knl, *pe_curknl;
--
2.17.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH] x86/mm/dump_pagetables: Change to use DEFINE_SHOW_ATTRIBUTE macro
2018-11-19 15:43 [PATCH] x86/mm/dump_pagetables: Change to use DEFINE_SHOW_ATTRIBUTE macro Yangtao Li
@ 2018-11-19 17:06 ` Dave Hansen
2018-11-20 0:49 ` Frank Lee
2018-11-27 22:50 ` Kees Cook
2018-12-18 12:09 ` [tip:x86/mm] x86/mm/dump_pagetables: Use DEFINE_SHOW_ATTRIBUTE() tip-bot for Yangtao Li
1 sibling, 2 replies; 9+ messages in thread
From: Dave Hansen @ 2018-11-19 17:06 UTC (permalink / raw)
To: Yangtao Li, keescook, dave.hansen, luto, peterz, tglx, mingo, bp, hpa
Cc: x86, linux-kernel
On 11/19/18 7:43 AM, Yangtao Li wrote:
> -static const struct file_operations ptdump_curusr_fops = {
> - .owner = THIS_MODULE,
> - .open = ptdump_open_curusr,
> - .read = seq_read,
> - .llseek = seq_lseek,
> - .release = single_release,
> -};
> +DEFINE_SHOW_ATTRIBUTE(ptdump_curusr);
FWIW, I rather dislike this conversion and the DEFINE_SHOW_ATTRIBUTE()
approach in general. It makes it basically impossible to go from
ptdump_curusr to ptdump_open_curusr without opening up the macro and
reverse-engineering it.
My test is that for these macros to be sane, I need to be able to find
"ptdump_open_curusr" by grepping for "ptdump_curusr". This fails the test.
I don't think saving a few lines of code is worth the obfuscation.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] x86/mm/dump_pagetables: Change to use DEFINE_SHOW_ATTRIBUTE macro
2018-11-19 17:06 ` Dave Hansen
@ 2018-11-20 0:49 ` Frank Lee
2018-11-20 0:50 ` Frank Lee
2018-11-27 22:50 ` Kees Cook
1 sibling, 1 reply; 9+ messages in thread
From: Frank Lee @ 2018-11-20 0:49 UTC (permalink / raw)
To: dave.hansen
Cc: Kees Cook, dave.hansen, luto, peterz, tglx, mingo, bp, hpa, x86,
linux-kernel, Yangtao Li
Hi Dava:
How about just change the ptdump_fops and ptdump_open?
Yours,
Yangtao
On Tue, Nov 20, 2018 at 1:06 AM Dave Hansen <dave.hansen@intel.com> wrote:
>
> On 11/19/18 7:43 AM, Yangtao Li wrote:
> > -static const struct file_operations ptdump_curusr_fops = {
> > - .owner = THIS_MODULE,
> > - .open = ptdump_open_curusr,
> > - .read = seq_read,
> > - .llseek = seq_lseek,
> > - .release = single_release,
> > -};
> > +DEFINE_SHOW_ATTRIBUTE(ptdump_curusr);
>
> FWIW, I rather dislike this conversion and the DEFINE_SHOW_ATTRIBUTE()
> approach in general. It makes it basically impossible to go from
> ptdump_curusr to ptdump_open_curusr without opening up the macro and
> reverse-engineering it.
>
> My test is that for these macros to be sane, I need to be able to find
> "ptdump_open_curusr" by grepping for "ptdump_curusr". This fails the test.
>
> I don't think saving a few lines of code is worth the obfuscation.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] x86/mm/dump_pagetables: Change to use DEFINE_SHOW_ATTRIBUTE macro
2018-11-20 0:49 ` Frank Lee
@ 2018-11-20 0:50 ` Frank Lee
0 siblings, 0 replies; 9+ messages in thread
From: Frank Lee @ 2018-11-20 0:50 UTC (permalink / raw)
To: dave.hansen
Cc: Kees Cook, dave.hansen, luto, peterz, tglx, mingo, bp, hpa, x86,
linux-kernel
Hi Kees:
I want to listen to you.
--Yangtao
On Tue, Nov 20, 2018 at 8:49 AM Frank Lee <tiny.windzz@gmail.com> wrote:
>
> Hi Dava:
>
> How about just change the ptdump_fops and ptdump_open?
>
> Yours,
> Yangtao
> On Tue, Nov 20, 2018 at 1:06 AM Dave Hansen <dave.hansen@intel.com> wrote:
> >
> > On 11/19/18 7:43 AM, Yangtao Li wrote:
> > > -static const struct file_operations ptdump_curusr_fops = {
> > > - .owner = THIS_MODULE,
> > > - .open = ptdump_open_curusr,
> > > - .read = seq_read,
> > > - .llseek = seq_lseek,
> > > - .release = single_release,
> > > -};
> > > +DEFINE_SHOW_ATTRIBUTE(ptdump_curusr);
> >
> > FWIW, I rather dislike this conversion and the DEFINE_SHOW_ATTRIBUTE()
> > approach in general. It makes it basically impossible to go from
> > ptdump_curusr to ptdump_open_curusr without opening up the macro and
> > reverse-engineering it.
> >
> > My test is that for these macros to be sane, I need to be able to find
> > "ptdump_open_curusr" by grepping for "ptdump_curusr". This fails the test.
> >
> > I don't think saving a few lines of code is worth the obfuscation.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] x86/mm/dump_pagetables: Change to use DEFINE_SHOW_ATTRIBUTE macro
2018-11-19 17:06 ` Dave Hansen
2018-11-20 0:49 ` Frank Lee
@ 2018-11-27 22:50 ` Kees Cook
2018-11-28 0:57 ` Frank Lee
2018-11-28 18:44 ` Dave Hansen
1 sibling, 2 replies; 9+ messages in thread
From: Kees Cook @ 2018-11-27 22:50 UTC (permalink / raw)
To: Dave Hansen
Cc: Yangtao Li, Dave Hansen, Andy Lutomirski, Peter Zijlstra,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, H. Peter Anvin,
X86 ML, LKML
On Mon, Nov 19, 2018 at 9:06 AM, Dave Hansen <dave.hansen@intel.com> wrote:
> On 11/19/18 7:43 AM, Yangtao Li wrote:
>> -static const struct file_operations ptdump_curusr_fops = {
>> - .owner = THIS_MODULE,
>> - .open = ptdump_open_curusr,
>> - .read = seq_read,
>> - .llseek = seq_lseek,
>> - .release = single_release,
>> -};
>> +DEFINE_SHOW_ATTRIBUTE(ptdump_curusr);
>
> FWIW, I rather dislike this conversion and the DEFINE_SHOW_ATTRIBUTE()
> approach in general. It makes it basically impossible to go from
> ptdump_curusr to ptdump_open_curusr without opening up the macro and
> reverse-engineering it.
>
> My test is that for these macros to be sane, I need to be able to find
> "ptdump_open_curusr" by grepping for "ptdump_curusr". This fails the test.
Er, "ptdump_curusr" matches the generated name "ptdump_curusr_show",
is that what you mean?
> I don't think saving a few lines of code is worth the obfuscation.
This is the standard boilerplate for attributes, though. I'd be nice
to drop all the copy/pasted code...
--
Kees Cook
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] x86/mm/dump_pagetables: Change to use DEFINE_SHOW_ATTRIBUTE macro
2018-11-27 22:50 ` Kees Cook
@ 2018-11-28 0:57 ` Frank Lee
2018-11-28 18:44 ` Dave Hansen
1 sibling, 0 replies; 9+ messages in thread
From: Frank Lee @ 2018-11-28 0:57 UTC (permalink / raw)
To: Kees Cook
Cc: dave.hansen, dave.hansen, luto, peterz, tglx, mingo, bp, hpa,
x86, linux-kernel
On Wed, Nov 28, 2018 at 6:50 AM Kees Cook <keescook@chromium.org> wrote:
>
> On Mon, Nov 19, 2018 at 9:06 AM, Dave Hansen <dave.hansen@intel.com> wrote:
> > On 11/19/18 7:43 AM, Yangtao Li wrote:
> >> -static const struct file_operations ptdump_curusr_fops = {
> >> - .owner = THIS_MODULE,
> >> - .open = ptdump_open_curusr,
> >> - .read = seq_read,
> >> - .llseek = seq_lseek,
> >> - .release = single_release,
> >> -};
> >> +DEFINE_SHOW_ATTRIBUTE(ptdump_curusr);
> >
> > FWIW, I rather dislike this conversion and the DEFINE_SHOW_ATTRIBUTE()
> > approach in general. It makes it basically impossible to go from
> > ptdump_curusr to ptdump_open_curusr without opening up the macro and
> > reverse-engineering it.
> >
> > My test is that for these macros to be sane, I need to be able to find
> > "ptdump_open_curusr" by grepping for "ptdump_curusr". This fails the test.
>
> Er, "ptdump_curusr" matches the generated name "ptdump_curusr_show",
> is that what you mean?
>
> > I don't think saving a few lines of code is worth the obfuscation.
>
> This is the standard boilerplate for attributes, though. I'd be nice
> to drop all the copy/pasted code...
>
> --
> Kees Cook
I also think that we should delete the duplicate code which doesn't
make much sense.
MBR,
Yangtao
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] x86/mm/dump_pagetables: Change to use DEFINE_SHOW_ATTRIBUTE macro
2018-11-27 22:50 ` Kees Cook
2018-11-28 0:57 ` Frank Lee
@ 2018-11-28 18:44 ` Dave Hansen
2018-11-29 21:28 ` Kees Cook
1 sibling, 1 reply; 9+ messages in thread
From: Dave Hansen @ 2018-11-28 18:44 UTC (permalink / raw)
To: Kees Cook
Cc: Yangtao Li, Andy Lutomirski, Peter Zijlstra, Thomas Gleixner,
Ingo Molnar, Borislav Petkov, H. Peter Anvin, X86 ML, LKML
On 11/27/18 2:50 PM, Kees Cook wrote:
> On Mon, Nov 19, 2018 at 9:06 AM, Dave Hansen <dave.hansen@intel.com> wrote:
>> On 11/19/18 7:43 AM, Yangtao Li wrote:
>>> -static const struct file_operations ptdump_curusr_fops = {
>>> - .owner = THIS_MODULE,
>>> - .open = ptdump_open_curusr,
>>> - .read = seq_read,
>>> - .llseek = seq_lseek,
>>> - .release = single_release,
>>> -};
>>> +DEFINE_SHOW_ATTRIBUTE(ptdump_curusr);
>>
>> FWIW, I rather dislike this conversion and the DEFINE_SHOW_ATTRIBUTE()
>> approach in general. It makes it basically impossible to go from
>> ptdump_curusr to ptdump_open_curusr without opening up the macro and
>> reverse-engineering it.
>>
>> My test is that for these macros to be sane, I need to be able to find
>> "ptdump_open_curusr" by grepping for "ptdump_curusr". This fails the test.
>
> Er, "ptdump_curusr" matches the generated name "ptdump_curusr_show",
> is that what you mean?
Ahh, I also missed some of the renames to make this OK, like:
> -static int ptdump_show_efi(struct seq_file *m, void *v)
> +static int ptdump_efi_show(struct seq_file *m, void *v)
I thought there was some macro magic going on that screwed the names up.
This looks fine to me.
Reviewed-by: Dave Hansen <dave.hansen@linux.intel.com>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] x86/mm/dump_pagetables: Change to use DEFINE_SHOW_ATTRIBUTE macro
2018-11-28 18:44 ` Dave Hansen
@ 2018-11-29 21:28 ` Kees Cook
0 siblings, 0 replies; 9+ messages in thread
From: Kees Cook @ 2018-11-29 21:28 UTC (permalink / raw)
To: Dave Hansen, Yangtao Li, Ingo Molnar
Cc: Andy Lutomirski, Peter Zijlstra, Thomas Gleixner,
Borislav Petkov, H. Peter Anvin, X86 ML, LKML
On Wed, Nov 28, 2018 at 10:45 AM Dave Hansen <dave.hansen@intel.com> wrote:
>
> On 11/27/18 2:50 PM, Kees Cook wrote:
> > On Mon, Nov 19, 2018 at 9:06 AM, Dave Hansen <dave.hansen@intel.com> wrote:
> >> On 11/19/18 7:43 AM, Yangtao Li wrote:
> >>> -static const struct file_operations ptdump_curusr_fops = {
> >>> - .owner = THIS_MODULE,
> >>> - .open = ptdump_open_curusr,
> >>> - .read = seq_read,
> >>> - .llseek = seq_lseek,
> >>> - .release = single_release,
> >>> -};
> >>> +DEFINE_SHOW_ATTRIBUTE(ptdump_curusr);
> >>
> >> FWIW, I rather dislike this conversion and the DEFINE_SHOW_ATTRIBUTE()
> >> approach in general. It makes it basically impossible to go from
> >> ptdump_curusr to ptdump_open_curusr without opening up the macro and
> >> reverse-engineering it.
> >>
> >> My test is that for these macros to be sane, I need to be able to find
> >> "ptdump_open_curusr" by grepping for "ptdump_curusr". This fails the test.
> >
> > Er, "ptdump_curusr" matches the generated name "ptdump_curusr_show",
> > is that what you mean?
>
> Ahh, I also missed some of the renames to make this OK, like:
>
> > -static int ptdump_show_efi(struct seq_file *m, void *v)
> > +static int ptdump_efi_show(struct seq_file *m, void *v)
>
> I thought there was some macro magic going on that screwed the names up.
>
> This looks fine to me.
>
> Reviewed-by: Dave Hansen <dave.hansen@linux.intel.com>
Cool, thanks!
Reviewed-by: Kees Cook <keescook@chromium.org>
Ingo, can you toss this in -tip please?
--
Kees Cook
^ permalink raw reply [flat|nested] 9+ messages in thread
* [tip:x86/mm] x86/mm/dump_pagetables: Use DEFINE_SHOW_ATTRIBUTE()
2018-11-19 15:43 [PATCH] x86/mm/dump_pagetables: Change to use DEFINE_SHOW_ATTRIBUTE macro Yangtao Li
2018-11-19 17:06 ` Dave Hansen
@ 2018-12-18 12:09 ` tip-bot for Yangtao Li
1 sibling, 0 replies; 9+ messages in thread
From: tip-bot for Yangtao Li @ 2018-12-18 12:09 UTC (permalink / raw)
To: linux-tip-commits
Cc: linux-kernel, tiny.windzz, mingo, dave.hansen, hpa, tglx
Commit-ID: 6848ac7ca39a226ede5df7af0efcc4ef0611e99c
Gitweb: https://git.kernel.org/tip/6848ac7ca39a226ede5df7af0efcc4ef0611e99c
Author: Yangtao Li <tiny.windzz@gmail.com>
AuthorDate: Mon, 19 Nov 2018 10:43:34 -0500
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitDate: Tue, 18 Dec 2018 13:05:54 +0100
x86/mm/dump_pagetables: Use DEFINE_SHOW_ATTRIBUTE()
Use DEFINE_SHOW_ATTRIBUTE() instead of open coding it.
Signed-off-by: Yangtao Li <tiny.windzz@gmail.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Dave Hansen <dave.hansen@linux.intel.com>
Cc: keescook@chromium.org
Cc: luto@kernel.org
Cc: peterz@infradead.org
Cc: bp@alien8.de
Cc: hpa@zytor.com
Link: https://lkml.kernel.org/r/20181119154334.18265-1-tiny.windzz@gmail.com
---
arch/x86/mm/debug_pagetables.c | 58 +++++-------------------------------------
1 file changed, 7 insertions(+), 51 deletions(-)
diff --git a/arch/x86/mm/debug_pagetables.c b/arch/x86/mm/debug_pagetables.c
index 225fe2f0bfec..cd84f067e41d 100644
--- a/arch/x86/mm/debug_pagetables.c
+++ b/arch/x86/mm/debug_pagetables.c
@@ -10,20 +10,9 @@ static int ptdump_show(struct seq_file *m, void *v)
return 0;
}
-static int ptdump_open(struct inode *inode, struct file *filp)
-{
- return single_open(filp, ptdump_show, NULL);
-}
-
-static const struct file_operations ptdump_fops = {
- .owner = THIS_MODULE,
- .open = ptdump_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
+DEFINE_SHOW_ATTRIBUTE(ptdump);
-static int ptdump_show_curknl(struct seq_file *m, void *v)
+static int ptdump_curknl_show(struct seq_file *m, void *v)
{
if (current->mm->pgd) {
down_read(¤t->mm->mmap_sem);
@@ -33,23 +22,12 @@ static int ptdump_show_curknl(struct seq_file *m, void *v)
return 0;
}
-static int ptdump_open_curknl(struct inode *inode, struct file *filp)
-{
- return single_open(filp, ptdump_show_curknl, NULL);
-}
-
-static const struct file_operations ptdump_curknl_fops = {
- .owner = THIS_MODULE,
- .open = ptdump_open_curknl,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
+DEFINE_SHOW_ATTRIBUTE(ptdump_curknl);
#ifdef CONFIG_PAGE_TABLE_ISOLATION
static struct dentry *pe_curusr;
-static int ptdump_show_curusr(struct seq_file *m, void *v)
+static int ptdump_curusr_show(struct seq_file *m, void *v)
{
if (current->mm->pgd) {
down_read(¤t->mm->mmap_sem);
@@ -59,42 +37,20 @@ static int ptdump_show_curusr(struct seq_file *m, void *v)
return 0;
}
-static int ptdump_open_curusr(struct inode *inode, struct file *filp)
-{
- return single_open(filp, ptdump_show_curusr, NULL);
-}
-
-static const struct file_operations ptdump_curusr_fops = {
- .owner = THIS_MODULE,
- .open = ptdump_open_curusr,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
+DEFINE_SHOW_ATTRIBUTE(ptdump_curusr);
#endif
#if defined(CONFIG_EFI) && defined(CONFIG_X86_64)
static struct dentry *pe_efi;
-static int ptdump_show_efi(struct seq_file *m, void *v)
+static int ptdump_efi_show(struct seq_file *m, void *v)
{
if (efi_mm.pgd)
ptdump_walk_pgd_level_debugfs(m, efi_mm.pgd, false);
return 0;
}
-static int ptdump_open_efi(struct inode *inode, struct file *filp)
-{
- return single_open(filp, ptdump_show_efi, NULL);
-}
-
-static const struct file_operations ptdump_efi_fops = {
- .owner = THIS_MODULE,
- .open = ptdump_open_efi,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
+DEFINE_SHOW_ATTRIBUTE(ptdump_efi);
#endif
static struct dentry *dir, *pe_knl, *pe_curknl;
^ permalink raw reply related [flat|nested] 9+ messages in thread
end of thread, other threads:[~2018-12-18 12:10 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-11-19 15:43 [PATCH] x86/mm/dump_pagetables: Change to use DEFINE_SHOW_ATTRIBUTE macro Yangtao Li
2018-11-19 17:06 ` Dave Hansen
2018-11-20 0:49 ` Frank Lee
2018-11-20 0:50 ` Frank Lee
2018-11-27 22:50 ` Kees Cook
2018-11-28 0:57 ` Frank Lee
2018-11-28 18:44 ` Dave Hansen
2018-11-29 21:28 ` Kees Cook
2018-12-18 12:09 ` [tip:x86/mm] x86/mm/dump_pagetables: Use DEFINE_SHOW_ATTRIBUTE() tip-bot for Yangtao Li
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).