All of lore.kernel.org
 help / color / mirror / Atom feed
From: Youling Tang <youling.tang@linux.dev>
To: "Mika Penttilä" <mika.penttila@mbosol.com>,
	"Arnd Bergmann" <arnd@arndb.de>,
	"Luis Chamberlain" <mcgrof@kernel.org>,
	"Chris Mason" <clm@fb.com>, "Josef Bacik" <josef@toxicpanda.com>,
	"David Sterba" <dsterba@suse.com>,
	tytso@mit.edu, "Andreas Dilger" <adilger.kernel@dilger.ca>,
	"Jaegeuk Kim" <jaegeuk@kernel.org>, "Chao Yu" <chao@kernel.org>,
	"Christoph Hellwig" <hch@infradead.org>
Cc: linux-arch@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-modules@vger.kernel.org, linux-btrfs@vger.kernel.org,
	linux-ext4@vger.kernel.org,
	linux-f2fs-devel@lists.sourceforge.net,
	Youling Tang <tangyouling@kylinos.cn>
Subject: Re: [PATCH 1/4] module: Add module_subinit{_noexit} and module_subeixt helper macros
Date: Wed, 24 Jul 2024 09:20:17 +0800	[thread overview]
Message-ID: <da41a162-9f6d-4607-9055-ffc21fe1771e@linux.dev> (raw)
In-Reply-To: <4570c972-de09-4818-bd1b-3112f651b49d@mbosol.com>

Hi, Mika

On 23/07/2024 17:58, Mika Penttilä wrote:
> On 7/23/24 11:32, Youling Tang wrote:
>> From: Youling Tang <tangyouling@kylinos.cn>
>>
>> In theory init/exit should match their sequence, thus normally they should
>> look like this:
>> -------------------------+------------------------
>>      init_A();            |
>>      init_B();            |
>>      init_C();            |
>>                           |   exit_C();
>>                           |   exit_B();
>>                           |   exit_A();
>>
>> Providing module_subinit{_noexit} and module_subeixt helps macros ensure
>> that modules init/exit match their order, while also simplifying the code.
>>
>> The three macros are defined as follows:
>> - module_subinit(initfn, exitfn,rollback)
>> - module_subinit_noexit(initfn, rollback)
>> - module_subexit(rollback)
>>
>> `initfn` is the initialization function and `exitfn` is the corresponding
>> exit function.
>>
>> Signed-off-by: Youling Tang <tangyouling@kylinos.cn>
>> ---
>>   include/asm-generic/vmlinux.lds.h |  5 +++
>>   include/linux/init.h              | 62 ++++++++++++++++++++++++++++++-
>>   include/linux/module.h            | 22 +++++++++++
>>   3 files changed, 88 insertions(+), 1 deletion(-)
>>
>> diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
>> index 677315e51e54..48ccac7c6448 100644
>> --- a/include/asm-generic/vmlinux.lds.h
>> +++ b/include/asm-generic/vmlinux.lds.h
>> @@ -927,6 +927,10 @@
>>   		INIT_CALLS_LEVEL(7)					\
>>   		__initcall_end = .;
>>   
>> +#define SUBINIT_CALL							\
>> +		*(.subinitcall.init)					\
>> +		*(.subexitcall.exit)
>> +
>>   #define CON_INITCALL							\
>>   	BOUNDED_SECTION_POST_LABEL(.con_initcall.init, __con_initcall, _start, _end)
>>   
>> @@ -1155,6 +1159,7 @@
>>   		INIT_DATA						\
>>   		INIT_SETUP(initsetup_align)				\
>>   		INIT_CALLS						\
>> +		SUBINIT_CALL						\
>>   		CON_INITCALL						\
>>   		INIT_RAM_FS						\
>>   	}
>> diff --git a/include/linux/init.h b/include/linux/init.h
>> index ee1309473bc6..e8689ff2cb6c 100644
>> --- a/include/linux/init.h
>> +++ b/include/linux/init.h
>> @@ -55,6 +55,9 @@
>>   #define __exitdata	__section(".exit.data")
>>   #define __exit_call	__used __section(".exitcall.exit")
>>   
>> +#define __subinit_call	__used __section(".subinitcall.init")
>> +#define __subexit_call	__used __section(".subexitcall.exit")
>> +
>>   /*
>>    * modpost check for section mismatches during the kernel build.
>>    * A section mismatch happens when there are references from a
>> @@ -115,6 +118,9 @@
>>   typedef int (*initcall_t)(void);
>>   typedef void (*exitcall_t)(void);
>>   
>> +typedef int (*subinitcall_t)(void);
>> +typedef void (*subexitcall_t)(void);
>> +
>>   #ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS
>>   typedef int initcall_entry_t;
>>   
>> @@ -183,7 +189,61 @@ extern struct module __this_module;
>>   #endif
>>   
>>   #endif
>> -
>> +
>> +#ifndef __ASSEMBLY__
>> +struct subexitcall_rollback {
>> +	/*
>> +	 * Records the address of the first sub-initialization function in the
>> +	 * ".subexitcall.exit" section
>> +	 */
>> +	unsigned long first_addr;
>> +	int ncalls;
>> +};
>> +
>> +static inline void __subexitcall_rollback(struct subexitcall_rollback *r)
>> +{
>> +	unsigned long addr = r->first_addr - sizeof(r->first_addr) * (r->ncalls - 1);
>> +
>> +	for (; r->ncalls--; addr += sizeof(r->first_addr)) {
>> +		unsigned long *tmp = (void *)addr;
>> +		subexitcall_t fn = (subexitcall_t)*tmp;
>> +		fn();
>> +	}
>> +}
> How does this guarantee the exit calls match sequence? Are you assuming
> linker puts exit functions in reverse order?
Take btrfs for example:
Initialize the function sequentially in init_btrfs_fs() using
module_subinit{_noexit}, storing the corresponding function addresses
in the specified ".subinitcall.init" and ".subexitcall.exit" sections.

Using gcc to compile btrfs to.ko, the view section contains the following:
```
$ objdump -d -j ".subinitcall.init" fs/btrfs/super.o

fs/btrfs/super.o:     file format elf64-x86-64


Disassembly of section .subinitcall.init:

0000000000000000 <__subinitcall_register_btrfs.0>:
     ...

0000000000000008 <__subinitcall_btrfs_run_sanity_tests.2>:
     ...

0000000000000010 <__subinitcall_btrfs_print_mod_info.3>:
     ...

0000000000000018 <__subinitcall_btrfs_interface_init.4>:
     ...

0000000000000020 <__subinitcall_btrfs_prelim_ref_init.6>:
     ...

0000000000000028 <__subinitcall_btrfs_delayed_ref_init.8>:
     ...

0000000000000030 <__subinitcall_btrfs_auto_defrag_init.10>:
     ...

0000000000000038 <__subinitcall_btrfs_delayed_inode_init.12>:
     ...

0000000000000040 <__subinitcall_ordered_data_init.14>:
     ...

0000000000000048 <__subinitcall_extent_map_init.16>:
     ...

0000000000000050 <__subinitcall_btrfs_bioset_init.18>:
     ...

0000000000000058 <__subinitcall_extent_buffer_init_cachep.20>:
     ...

0000000000000060 <__subinitcall_extent_state_init_cachep.22>:
     ...

0000000000000068 <__subinitcall_btrfs_free_space_init.24>:
     ...

0000000000000070 <__subinitcall_btrfs_ctree_init.26>:
     ...

0000000000000078 <__subinitcall_btrfs_transaction_init.28>:
     ...

0000000000000080 <__subinitcall_btrfs_init_dio.30>:
     ...

0000000000000088 <__subinitcall_btrfs_init_cachep.32>:
     ...

0000000000000090 <__subinitcall_btrfs_init_compress.34>:
     ...

0000000000000098 <__subinitcall_btrfs_init_sysfs.36>:
     ...

00000000000000a0 <__subinitcall_btrfs_props_init.38>:
     ...

```

```
$ objdump -d -j ".subexitcall.exit" fs/btrfs/super.o

fs/btrfs/super.o:     file format elf64-x86-64


Disassembly of section .subexitcall.exit:

0000000000000000 <__subexitcall_unregister_btrfs.1>:
     ...

0000000000000008 <__subexitcall_btrfs_interface_exit.5>:
     ...

0000000000000010 <__subexitcall_btrfs_prelim_ref_exit.7>:
     ...

0000000000000018 <__subexitcall_btrfs_delayed_ref_exit.9>:
     ...

0000000000000020 <__subexitcall_btrfs_auto_defrag_exit.11>:
     ...

0000000000000028 <__subexitcall_btrfs_delayed_inode_exit.13>:
     ...

0000000000000030 <__subexitcall_ordered_data_exit.15>:
     ...

0000000000000038 <__subexitcall_extent_map_exit.17>:
     ...

0000000000000040 <__subexitcall_btrfs_bioset_exit.19>:
     ...

0000000000000048 <__subexitcall_extent_buffer_free_cachep.21>:
     ...

0000000000000050 <__subexitcall_extent_state_free_cachep.23>:
     ...

0000000000000058 <__subexitcall_btrfs_free_space_exit.25>:
     ...

0000000000000060 <__subexitcall_btrfs_ctree_exit.27>:
     ...

0000000000000068 <__subexitcall_btrfs_transaction_exit.29>:
     ...

0000000000000070 <__subexitcall_btrfs_destroy_dio.31>:
     ...

0000000000000078 <__subexitcall_btrfs_destroy_cachep.33>:
     ...

0000000000000080 <__subexitcall_btrfs_exit_compress.35>:
     ...

0000000000000088 <__subexitcall_btrfs_exit_sysfs.37>:
     ...


```

 From the above, we can see that the compiler stores the init/exit function
in reverse order.

Thanks,
Youling.

WARNING: multiple messages have this Message-ID (diff)
From: Youling Tang <youling.tang@linux.dev>
To: "Mika Penttilä" <mika.penttila@mbosol.com>,
	"Arnd Bergmann" <arnd@arndb.de>,
	"Luis Chamberlain" <mcgrof@kernel.org>,
	"Chris Mason" <clm@fb.com>, "Josef Bacik" <josef@toxicpanda.com>,
	"David Sterba" <dsterba@suse.com>,
	tytso@mit.edu, "Andreas Dilger" <adilger.kernel@dilger.ca>,
	"Jaegeuk Kim" <jaegeuk@kernel.org>, "Chao Yu" <chao@kernel.org>,
	"Christoph Hellwig" <hch@infradead.org>
Cc: linux-arch@vger.kernel.org, Youling Tang <tangyouling@kylinos.cn>,
	linux-kernel@vger.kernel.org,
	linux-f2fs-devel@lists.sourceforge.net,
	linux-modules@vger.kernel.org, linux-ext4@vger.kernel.org,
	linux-btrfs@vger.kernel.org
Subject: Re: [f2fs-dev] [PATCH 1/4] module: Add module_subinit{_noexit} and module_subeixt helper macros
Date: Wed, 24 Jul 2024 09:20:17 +0800	[thread overview]
Message-ID: <da41a162-9f6d-4607-9055-ffc21fe1771e@linux.dev> (raw)
In-Reply-To: <4570c972-de09-4818-bd1b-3112f651b49d@mbosol.com>

Hi, Mika

On 23/07/2024 17:58, Mika Penttilä wrote:
> On 7/23/24 11:32, Youling Tang wrote:
>> From: Youling Tang <tangyouling@kylinos.cn>
>>
>> In theory init/exit should match their sequence, thus normally they should
>> look like this:
>> -------------------------+------------------------
>>      init_A();            |
>>      init_B();            |
>>      init_C();            |
>>                           |   exit_C();
>>                           |   exit_B();
>>                           |   exit_A();
>>
>> Providing module_subinit{_noexit} and module_subeixt helps macros ensure
>> that modules init/exit match their order, while also simplifying the code.
>>
>> The three macros are defined as follows:
>> - module_subinit(initfn, exitfn,rollback)
>> - module_subinit_noexit(initfn, rollback)
>> - module_subexit(rollback)
>>
>> `initfn` is the initialization function and `exitfn` is the corresponding
>> exit function.
>>
>> Signed-off-by: Youling Tang <tangyouling@kylinos.cn>
>> ---
>>   include/asm-generic/vmlinux.lds.h |  5 +++
>>   include/linux/init.h              | 62 ++++++++++++++++++++++++++++++-
>>   include/linux/module.h            | 22 +++++++++++
>>   3 files changed, 88 insertions(+), 1 deletion(-)
>>
>> diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
>> index 677315e51e54..48ccac7c6448 100644
>> --- a/include/asm-generic/vmlinux.lds.h
>> +++ b/include/asm-generic/vmlinux.lds.h
>> @@ -927,6 +927,10 @@
>>   		INIT_CALLS_LEVEL(7)					\
>>   		__initcall_end = .;
>>   
>> +#define SUBINIT_CALL							\
>> +		*(.subinitcall.init)					\
>> +		*(.subexitcall.exit)
>> +
>>   #define CON_INITCALL							\
>>   	BOUNDED_SECTION_POST_LABEL(.con_initcall.init, __con_initcall, _start, _end)
>>   
>> @@ -1155,6 +1159,7 @@
>>   		INIT_DATA						\
>>   		INIT_SETUP(initsetup_align)				\
>>   		INIT_CALLS						\
>> +		SUBINIT_CALL						\
>>   		CON_INITCALL						\
>>   		INIT_RAM_FS						\
>>   	}
>> diff --git a/include/linux/init.h b/include/linux/init.h
>> index ee1309473bc6..e8689ff2cb6c 100644
>> --- a/include/linux/init.h
>> +++ b/include/linux/init.h
>> @@ -55,6 +55,9 @@
>>   #define __exitdata	__section(".exit.data")
>>   #define __exit_call	__used __section(".exitcall.exit")
>>   
>> +#define __subinit_call	__used __section(".subinitcall.init")
>> +#define __subexit_call	__used __section(".subexitcall.exit")
>> +
>>   /*
>>    * modpost check for section mismatches during the kernel build.
>>    * A section mismatch happens when there are references from a
>> @@ -115,6 +118,9 @@
>>   typedef int (*initcall_t)(void);
>>   typedef void (*exitcall_t)(void);
>>   
>> +typedef int (*subinitcall_t)(void);
>> +typedef void (*subexitcall_t)(void);
>> +
>>   #ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS
>>   typedef int initcall_entry_t;
>>   
>> @@ -183,7 +189,61 @@ extern struct module __this_module;
>>   #endif
>>   
>>   #endif
>> -
>> +
>> +#ifndef __ASSEMBLY__
>> +struct subexitcall_rollback {
>> +	/*
>> +	 * Records the address of the first sub-initialization function in the
>> +	 * ".subexitcall.exit" section
>> +	 */
>> +	unsigned long first_addr;
>> +	int ncalls;
>> +};
>> +
>> +static inline void __subexitcall_rollback(struct subexitcall_rollback *r)
>> +{
>> +	unsigned long addr = r->first_addr - sizeof(r->first_addr) * (r->ncalls - 1);
>> +
>> +	for (; r->ncalls--; addr += sizeof(r->first_addr)) {
>> +		unsigned long *tmp = (void *)addr;
>> +		subexitcall_t fn = (subexitcall_t)*tmp;
>> +		fn();
>> +	}
>> +}
> How does this guarantee the exit calls match sequence? Are you assuming
> linker puts exit functions in reverse order?
Take btrfs for example:
Initialize the function sequentially in init_btrfs_fs() using
module_subinit{_noexit}, storing the corresponding function addresses
in the specified ".subinitcall.init" and ".subexitcall.exit" sections.

Using gcc to compile btrfs to.ko, the view section contains the following:
```
$ objdump -d -j ".subinitcall.init" fs/btrfs/super.o

fs/btrfs/super.o:     file format elf64-x86-64


Disassembly of section .subinitcall.init:

0000000000000000 <__subinitcall_register_btrfs.0>:
     ...

0000000000000008 <__subinitcall_btrfs_run_sanity_tests.2>:
     ...

0000000000000010 <__subinitcall_btrfs_print_mod_info.3>:
     ...

0000000000000018 <__subinitcall_btrfs_interface_init.4>:
     ...

0000000000000020 <__subinitcall_btrfs_prelim_ref_init.6>:
     ...

0000000000000028 <__subinitcall_btrfs_delayed_ref_init.8>:
     ...

0000000000000030 <__subinitcall_btrfs_auto_defrag_init.10>:
     ...

0000000000000038 <__subinitcall_btrfs_delayed_inode_init.12>:
     ...

0000000000000040 <__subinitcall_ordered_data_init.14>:
     ...

0000000000000048 <__subinitcall_extent_map_init.16>:
     ...

0000000000000050 <__subinitcall_btrfs_bioset_init.18>:
     ...

0000000000000058 <__subinitcall_extent_buffer_init_cachep.20>:
     ...

0000000000000060 <__subinitcall_extent_state_init_cachep.22>:
     ...

0000000000000068 <__subinitcall_btrfs_free_space_init.24>:
     ...

0000000000000070 <__subinitcall_btrfs_ctree_init.26>:
     ...

0000000000000078 <__subinitcall_btrfs_transaction_init.28>:
     ...

0000000000000080 <__subinitcall_btrfs_init_dio.30>:
     ...

0000000000000088 <__subinitcall_btrfs_init_cachep.32>:
     ...

0000000000000090 <__subinitcall_btrfs_init_compress.34>:
     ...

0000000000000098 <__subinitcall_btrfs_init_sysfs.36>:
     ...

00000000000000a0 <__subinitcall_btrfs_props_init.38>:
     ...

```

```
$ objdump -d -j ".subexitcall.exit" fs/btrfs/super.o

fs/btrfs/super.o:     file format elf64-x86-64


Disassembly of section .subexitcall.exit:

0000000000000000 <__subexitcall_unregister_btrfs.1>:
     ...

0000000000000008 <__subexitcall_btrfs_interface_exit.5>:
     ...

0000000000000010 <__subexitcall_btrfs_prelim_ref_exit.7>:
     ...

0000000000000018 <__subexitcall_btrfs_delayed_ref_exit.9>:
     ...

0000000000000020 <__subexitcall_btrfs_auto_defrag_exit.11>:
     ...

0000000000000028 <__subexitcall_btrfs_delayed_inode_exit.13>:
     ...

0000000000000030 <__subexitcall_ordered_data_exit.15>:
     ...

0000000000000038 <__subexitcall_extent_map_exit.17>:
     ...

0000000000000040 <__subexitcall_btrfs_bioset_exit.19>:
     ...

0000000000000048 <__subexitcall_extent_buffer_free_cachep.21>:
     ...

0000000000000050 <__subexitcall_extent_state_free_cachep.23>:
     ...

0000000000000058 <__subexitcall_btrfs_free_space_exit.25>:
     ...

0000000000000060 <__subexitcall_btrfs_ctree_exit.27>:
     ...

0000000000000068 <__subexitcall_btrfs_transaction_exit.29>:
     ...

0000000000000070 <__subexitcall_btrfs_destroy_dio.31>:
     ...

0000000000000078 <__subexitcall_btrfs_destroy_cachep.33>:
     ...

0000000000000080 <__subexitcall_btrfs_exit_compress.35>:
     ...

0000000000000088 <__subexitcall_btrfs_exit_sysfs.37>:
     ...


```

 From the above, we can see that the compiler stores the init/exit function
in reverse order.

Thanks,
Youling.


_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

  reply	other threads:[~2024-07-24  1:20 UTC|newest]

Thread overview: 64+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-07-23  8:32 [PATCH 0/4] Add module_subinit{_noexit} and module_subeixt helper macros Youling Tang
2024-07-23  8:32 ` [f2fs-dev] " Youling Tang
2024-07-23  8:32 ` [PATCH 1/4] module: " Youling Tang
2024-07-23  8:32   ` [f2fs-dev] " Youling Tang
2024-07-23  9:58   ` Mika Penttilä
2024-07-23  9:58     ` [f2fs-dev] " Mika Penttilä
2024-07-24  1:20     ` Youling Tang [this message]
2024-07-24  1:20       ` Youling Tang
2024-07-23 14:33   ` Christoph Hellwig
2024-07-23 14:33     ` [f2fs-dev] " Christoph Hellwig
2024-07-24  1:57     ` Youling Tang
2024-07-24  1:57       ` [f2fs-dev] " Youling Tang
2024-07-24 15:43       ` Christoph Hellwig
2024-07-24 15:43         ` [f2fs-dev] " Christoph Hellwig
2024-07-25  3:01         ` Youling Tang
2024-07-25  3:01           ` [f2fs-dev] " Youling Tang
2024-07-25 14:39           ` Christoph Hellwig
2024-07-25 14:39             ` [f2fs-dev] " Christoph Hellwig
2024-07-25 15:30             ` Arnd Bergmann
2024-07-25 15:30               ` [f2fs-dev] " Arnd Bergmann
2024-07-25 15:34               ` Christoph Hellwig
2024-07-25 15:34                 ` [f2fs-dev] " Christoph Hellwig
2024-07-25 17:14                 ` Goffredo Baroncelli
2024-07-25 17:14                   ` [f2fs-dev] " Goffredo Baroncelli via Linux-f2fs-devel
2024-07-25 19:46                   ` Christoph Hellwig
2024-07-25 19:46                     ` [f2fs-dev] " Christoph Hellwig
2024-07-26  8:54                     ` Youling Tang
2024-07-26  8:54                       ` [f2fs-dev] " Youling Tang
2024-07-26 14:04                       ` Christoph Hellwig
2024-07-26 14:04                         ` [f2fs-dev] " Christoph Hellwig
2024-07-26 15:22                         ` David Sterba
2024-07-26 15:22                           ` [f2fs-dev] " David Sterba
2024-07-26 17:58                           ` Theodore Ts'o
2024-07-26 17:58                             ` [f2fs-dev] " Theodore Ts'o
2024-07-26 18:09                             ` Christoph Hellwig
2024-07-26 18:09                               ` [f2fs-dev] " Christoph Hellwig
2024-07-26 22:45                               ` David Sterba
2024-07-26 22:45                                 ` [f2fs-dev] " David Sterba
2024-07-27 14:52                               ` Theodore Ts'o
2024-07-27 14:52                                 ` [f2fs-dev] " Theodore Ts'o
2024-07-29  1:46                                 ` Youling Tang
2024-07-29  1:46                                   ` [f2fs-dev] " Youling Tang
2024-07-29  2:44                                   ` Theodore Ts'o
2024-07-29  2:44                                     ` [f2fs-dev] " Theodore Ts'o
2024-07-29  3:01                                     ` Youling Tang
2024-07-29  3:01                                       ` [f2fs-dev] " Youling Tang
2024-07-29 18:57                                     ` Christoph Hellwig
2024-07-29 18:57                                       ` [f2fs-dev] " Christoph Hellwig
2024-07-23  8:32 ` [PATCH 2/4] btrfs: Use " Youling Tang
2024-07-23  8:32   ` [f2fs-dev] " Youling Tang
2024-07-23 22:24   ` kernel test robot
2024-07-23 22:24     ` [f2fs-dev] " kernel test robot
2024-07-24  6:29     ` Youling Tang
2024-07-24  6:29       ` [f2fs-dev] " Youling Tang
2024-07-23  8:32 ` [PATCH 3/4] ext4: Use module_{subinit, subexit} " Youling Tang
2024-07-23  8:32   ` [f2fs-dev] " Youling Tang
2024-07-23  8:32 ` [PATCH 4/4] f2fs: Use module_{subinit, subeixt} " Youling Tang
2024-07-23  8:32   ` [f2fs-dev] " Youling Tang
2024-07-23 18:51   ` kernel test robot
2024-07-23 18:51     ` [f2fs-dev] " kernel test robot
2024-07-24  2:14     ` Youling Tang
2024-07-24  2:14       ` [f2fs-dev] " Youling Tang
2024-07-23 21:31   ` kernel test robot
2024-07-23 21:31     ` [f2fs-dev] " kernel test robot

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=da41a162-9f6d-4607-9055-ffc21fe1771e@linux.dev \
    --to=youling.tang@linux.dev \
    --cc=adilger.kernel@dilger.ca \
    --cc=arnd@arndb.de \
    --cc=chao@kernel.org \
    --cc=clm@fb.com \
    --cc=dsterba@suse.com \
    --cc=hch@infradead.org \
    --cc=jaegeuk@kernel.org \
    --cc=josef@toxicpanda.com \
    --cc=linux-arch@vger.kernel.org \
    --cc=linux-btrfs@vger.kernel.org \
    --cc=linux-ext4@vger.kernel.org \
    --cc=linux-f2fs-devel@lists.sourceforge.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-modules@vger.kernel.org \
    --cc=mcgrof@kernel.org \
    --cc=mika.penttila@mbosol.com \
    --cc=tangyouling@kylinos.cn \
    --cc=tytso@mit.edu \
    /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.