From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
To: Arnd Bergmann <arnd@arndb.de>
Cc: paulmck@linux.vnet.ibm.com, linux-kernel@vger.kernel.org,
mingo@elte.hu, laijs@cn.fujitsu.com, dipankar@in.ibm.com,
akpm@linux-foundation.org, josh@joshtriplett.org,
dvhltc@us.ibm.com, niv@us.ibm.com, tglx@linutronix.de,
peterz@infradead.org, rostedt@goodmis.org,
Valdis.Kletnieks@vt.edu, dhowells@redhat.com
Subject: Re: [PATCH 02/10] rcu: annotated list rcu code
Date: Wed, 24 Feb 2010 15:15:09 -0500 [thread overview]
Message-ID: <20100224201509.GB21067@Krystal> (raw)
In-Reply-To: <1267041846-10469-3-git-send-email-arnd@arndb.de>
* Arnd Bergmann (arnd@arndb.de) wrote:
> The listrcu implementation now defines new rcu_list_head,
> rcu_hlist_head and rcu_hlist_entry structures that are
> annotated with __rcu. Only these can now be passed into
> rcu_list_for_each and related interfaces.
>
> When not running sparse, the types are defined to the
> original list_head etc in order to not break working
> setups that are lacking annotation.
Hrm, wait.. dumb question: how can an annotation break compilation ? If there is
any way out of this, I would prefer if we can do without a #ifdef __CHECKER__ if
possible. It calls for bugs and implementation mismatch.
Thanks,
Mathieu
>
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> ---
> include/linux/rculist.h | 152 ++++++++++++++++++++++++++++++++++------------
> 1 files changed, 112 insertions(+), 40 deletions(-)
>
> diff --git a/include/linux/rculist.h b/include/linux/rculist.h
> index 1bf0f70..dfbc6ea 100644
> --- a/include/linux/rculist.h
> +++ b/include/linux/rculist.h
> @@ -9,16 +9,67 @@
> #include <linux/list.h>
> #include <linux/rcupdate.h>
>
> +#ifdef __CHECKER__
> +struct rcu_list_head {
> + struct rcu_list_head __rcu *next;
> + struct rcu_list_head *prev;
> +};
> +#define LIST_HEAD_INIT_RCU(name) { (struct rcu_list_head __force __rcu *)&(name), &(name) }
> +
> +#define LIST_HEAD_RCU(name) \
> + struct rcu_list_head name = LIST_HEAD_INIT_RCU(name)
> +
> +static inline void INIT_LIST_HEAD_RCU(struct rcu_list_head *list)
> +{
> + __rcu_assign_pointer(list->next, list);
> + list->prev = list;
> +}
> +
> +struct rcu_hlist_head {
> + struct rcu_hlist_node __rcu *first;
> +};
> +
> +struct rcu_hlist_node {
> + struct rcu_hlist_node __rcu *next, **pprev;
> +};
> +
> +#define HLIST_HEAD_INIT_RCU { .first = (void __rcu __force *)NULL }
> +#define HLIST_HEAD_RCU(name) struct rcu_hlist_head name = \
> + { .first = (void __rcu __force *)NULL }
> +#define INIT_HLIST_HEAD_RCU(ptr) ((ptr)->first = (void __rcu __force *)NULL)
> +static inline void INIT_HLIST_NODE_RCU(struct rcu_hlist_node *h)
> +{
> + __rcu_assign_pointer(h->next, NULL);
> + h->pprev = NULL;
> +}
> +
> +#else /* !__CHECKER__ */
> +
> +#define rcu_list_head list_head
> +#define LIST_HEAD_INIT_RCU LIST_HEAD_INIT
> +#define LIST_HEAD_RCU LIST_HEAD
> +#define INIT_LIST_HEAD_RCU INIT_LIST_HEAD
> +
> +#define rcu_hlist_head hlist_head
> +#define rcu_hlist_node hlist_node
> +#define HLIST_HEAD_INIT_RCU HLIST_HEAD_INIT
> +#define HLIST_HEAD_RCU HLIST_HEAD
> +#define INIT_HLIST_HEAD_RCU INIT_HLIST_HEAD
> +#define INIT_HLIST_NODE_RCU INIT_HLIST_NODE
> +
> +#endif /* !__CHECKER__ */
> +
> +
> /*
> * Insert a new entry between two known consecutive entries.
> *
> * This is only for internal list manipulation where we know
> * the prev/next entries already!
> */
> -static inline void __list_add_rcu(struct list_head *new,
> - struct list_head *prev, struct list_head *next)
> +static inline void __list_add_rcu(struct rcu_list_head *new,
> + struct rcu_list_head *prev, struct rcu_list_head *next)
> {
> - new->next = next;
> + __rcu_assign_pointer(new->next, next);
> new->prev = prev;
> rcu_assign_pointer(prev->next, new);
> next->prev = new;
> @@ -40,9 +91,9 @@ static inline void __list_add_rcu(struct list_head *new,
> * the _rcu list-traversal primitives, such as
> * list_for_each_entry_rcu().
> */
> -static inline void list_add_rcu(struct list_head *new, struct list_head *head)
> +static inline void list_add_rcu(struct rcu_list_head *new, struct rcu_list_head *head)
> {
> - __list_add_rcu(new, head, head->next);
> + __list_add_rcu(new, head, __rcu_dereference(head->next));
> }
>
> /**
> @@ -61,8 +112,8 @@ static inline void list_add_rcu(struct list_head *new, struct list_head *head)
> * the _rcu list-traversal primitives, such as
> * list_for_each_entry_rcu().
> */
> -static inline void list_add_tail_rcu(struct list_head *new,
> - struct list_head *head)
> +static inline void list_add_tail_rcu(struct rcu_list_head *new,
> + struct rcu_list_head *head)
> {
> __list_add_rcu(new, head->prev, head);
> }
> @@ -91,13 +142,29 @@ static inline void list_add_tail_rcu(struct list_head *new,
> * or call_rcu() must be used to defer freeing until an RCU
> * grace period has elapsed.
> */
> -static inline void list_del_rcu(struct list_head *entry)
> +static inline void __list_del_rcu(struct rcu_list_head *prev, struct rcu_list_head *next)
> {
> - __list_del(entry->prev, entry->next);
> + next->prev = prev;
> + __rcu_assign_pointer(prev->next, next);
> +}
> +
> +static inline void list_del_rcu(struct rcu_list_head *entry)
> +{
> + __list_del_rcu(entry->prev, __rcu_dereference(entry->next));
> entry->prev = LIST_POISON2;
> }
>
> /**
> + * list_empty - tests whether a list is empty
> + * @head: the list to test.
> + */
> +static inline int list_empty_rcu(const struct rcu_list_head *head)
> +{
> + return rcu_dereference(head->next) == head;
> +}
> +
> +
> +/**
> * hlist_del_init_rcu - deletes entry from hash list with re-initialization
> * @n: the element to delete from the hash list.
> *
> @@ -117,7 +184,7 @@ static inline void list_del_rcu(struct list_head *entry)
> * perfectly legal to run concurrently with the _rcu list-traversal
> * primitives, such as hlist_for_each_entry_rcu().
> */
> -static inline void hlist_del_init_rcu(struct hlist_node *n)
> +static inline void hlist_del_init_rcu(struct rcu_hlist_node *n)
> {
> if (!hlist_unhashed(n)) {
> __hlist_del(n);
> @@ -133,13 +200,13 @@ static inline void hlist_del_init_rcu(struct hlist_node *n)
> * The @old entry will be replaced with the @new entry atomically.
> * Note: @old should not be empty.
> */
> -static inline void list_replace_rcu(struct list_head *old,
> - struct list_head *new)
> +static inline void list_replace_rcu(struct rcu_list_head *old,
> + struct rcu_list_head *new)
> {
> new->next = old->next;
> new->prev = old->prev;
> - rcu_assign_pointer(new->prev->next, new);
> - new->next->prev = new;
> + __rcu_assign_pointer(new->prev->next, new);
> + rcu_dereference(new->next)->prev = new;
> old->prev = LIST_POISON2;
> }
>
> @@ -160,13 +227,13 @@ static inline void list_replace_rcu(struct list_head *old,
> * based on call_rcu() could be created. But only if -really-
> * needed -- there is no shortage of RCU API members.
> */
> -static inline void list_splice_init_rcu(struct list_head *list,
> - struct list_head *head,
> +static inline void list_splice_init_rcu(struct rcu_list_head *list,
> + struct rcu_list_head *head,
> void (*sync)(void))
> {
> - struct list_head *first = list->next;
> - struct list_head *last = list->prev;
> - struct list_head *at = head->next;
> + struct rcu_list_head *first = __rcu_dereference(list->next);
> + struct rcu_list_head *last = list->prev;
> + struct rcu_list_head *at = __rcu_dereference(head->next);
>
> if (list_empty(head))
> return;
> @@ -192,7 +259,7 @@ static inline void list_splice_init_rcu(struct list_head *list,
> * this function.
> */
>
> - last->next = at;
> + __rcu_assign_pointer(last->next,at);
> rcu_assign_pointer(head->next, first);
> first->prev = head;
> at->prev = last;
> @@ -200,7 +267,7 @@ static inline void list_splice_init_rcu(struct list_head *list,
>
> /**
> * list_entry_rcu - get the struct for this entry
> - * @ptr: the &struct list_head pointer.
> + * @ptr: the &struct rcu_list_head pointer.
> * @type: the type of the struct this is embedded in.
> * @member: the name of the list_struct within the struct.
> *
> @@ -241,13 +308,13 @@ static inline void list_splice_init_rcu(struct list_head *list,
> */
> #define list_for_each_entry_rcu(pos, head, member) \
> for (pos = list_entry_rcu((head)->next, typeof(*pos), member); \
> - prefetch(pos->member.next), &pos->member != (head); \
> + prefetch(__rcu_dereference(pos->member.next)), &pos->member != (head); \
> pos = list_entry_rcu(pos->member.next, typeof(*pos), member))
>
>
> /**
> * list_for_each_continue_rcu
> - * @pos: the &struct list_head to use as a loop cursor.
> + * @pos: the &struct rcu_list_head to use as a loop cursor.
> * @head: the head for your list.
> *
> * Iterate over an rcu-protected list, continuing after current point.
> @@ -294,9 +361,9 @@ static inline void list_splice_init_rcu(struct list_head *list,
> * the _rcu list-traversal primitives, such as
> * hlist_for_each_entry().
> */
> -static inline void hlist_del_rcu(struct hlist_node *n)
> +static inline void hlist_del_rcu(struct rcu_hlist_node *n)
> {
> - __hlist_del(n);
> + __hlist_del((struct hlist_node *)n);
> n->pprev = LIST_POISON2;
> }
>
> @@ -307,16 +374,16 @@ static inline void hlist_del_rcu(struct hlist_node *n)
> *
> * The @old entry will be replaced with the @new entry atomically.
> */
> -static inline void hlist_replace_rcu(struct hlist_node *old,
> - struct hlist_node *new)
> +static inline void hlist_replace_rcu(struct rcu_hlist_node *old,
> + struct rcu_hlist_node *new)
> {
> - struct hlist_node *next = old->next;
> + struct rcu_hlist_node __rcu *next = old->next;
>
> new->next = next;
> new->pprev = old->pprev;
> rcu_assign_pointer(*new->pprev, new);
> if (next)
> - new->next->pprev = &new->next;
> + __rcu_dereference(new->next)->pprev = &new->next;
> old->pprev = LIST_POISON2;
> }
>
> @@ -339,12 +406,12 @@ static inline void hlist_replace_rcu(struct hlist_node *old,
> * problems on Alpha CPUs. Regardless of the type of CPU, the
> * list-traversal primitive must be guarded by rcu_read_lock().
> */
> -static inline void hlist_add_head_rcu(struct hlist_node *n,
> - struct hlist_head *h)
> +static inline void hlist_add_head_rcu(struct rcu_hlist_node *n,
> + struct rcu_hlist_head *h)
> {
> - struct hlist_node *first = h->first;
> + struct rcu_hlist_node *first = __rcu_dereference(h->first);
>
> - n->next = first;
> + __rcu_assign_pointer(n->next, first);
> n->pprev = &h->first;
> rcu_assign_pointer(h->first, n);
> if (first)
> @@ -369,8 +436,8 @@ static inline void hlist_add_head_rcu(struct hlist_node *n,
> * hlist_for_each_entry_rcu(), used to prevent memory-consistency
> * problems on Alpha CPUs.
> */
> -static inline void hlist_add_before_rcu(struct hlist_node *n,
> - struct hlist_node *next)
> +static inline void hlist_add_before_rcu(struct rcu_hlist_node *n,
> + struct rcu_hlist_node *next)
> {
> n->pprev = next->pprev;
> n->next = next;
> @@ -396,8 +463,8 @@ static inline void hlist_add_before_rcu(struct hlist_node *n,
> * hlist_for_each_entry_rcu(), used to prevent memory-consistency
> * problems on Alpha CPUs.
> */
> -static inline void hlist_add_after_rcu(struct hlist_node *prev,
> - struct hlist_node *n)
> +static inline void hlist_add_after_rcu(struct rcu_hlist_node *prev,
> + struct rcu_hlist_node *n)
> {
> n->next = prev->next;
> n->pprev = &prev->next;
> @@ -406,12 +473,17 @@ static inline void hlist_add_after_rcu(struct hlist_node *prev,
> n->next->pprev = &n->next;
> }
>
> +static inline int hlist_empty_rcu(const struct rcu_hlist_head *h)
> +{
> + return !__rcu_dereference(h->first);
> +}
> +
> /**
> * hlist_for_each_entry_rcu - iterate over rcu list of given type
> * @tpos: the type * to use as a loop cursor.
> - * @pos: the &struct hlist_node to use as a loop cursor.
> + * @pos: the &struct rcu_hlist_node to use as a loop cursor.
> * @head: the head for your list.
> - * @member: the name of the hlist_node within the struct.
> + * @member: the name of the rcu_hlist_node within the struct.
> *
> * This list-traversal primitive may safely run concurrently with
> * the _rcu list-mutation primitives such as hlist_add_head_rcu()
> @@ -419,7 +491,7 @@ static inline void hlist_add_after_rcu(struct hlist_node *prev,
> */
> #define hlist_for_each_entry_rcu(tpos, pos, head, member) \
> for (pos = rcu_dereference((head)->first); \
> - pos && ({ prefetch(pos->next); 1; }) && \
> + pos && ({ prefetch(__rcu_dereference(pos->next)); 1; }) && \
> ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1; }); \
> pos = rcu_dereference(pos->next))
>
> --
> 1.6.3.3
>
--
Mathieu Desnoyers
Operating System Efficiency Consultant
EfficiOS Inc.
http://www.efficios.com
next prev parent reply other threads:[~2010-02-24 20:15 UTC|newest]
Thread overview: 84+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-02-23 1:04 [PATCH tip/core/rcu 0/21] v6 add lockdep-based diagnostics to rcu_dereference() Paul E. McKenney
2010-02-23 1:04 ` [PATCH tip/core/rcu 01/21] rcu: introduce lockdep-based checking to RCU read-side primitives Paul E. McKenney
2010-02-25 10:09 ` [tip:core/rcu] rcu: Introduce " tip-bot for Paul E. McKenney
2010-02-23 1:04 ` [PATCH tip/core/rcu 02/21] rcu: add lockdep-enabled variants of rcu_dereference() Paul E. McKenney
2010-02-25 10:09 ` [tip:core/rcu] rcu: Add " tip-bot for Paul E. McKenney
2010-02-23 1:04 ` [PATCH tip/core/rcu 03/21] rcu: integrate rcu_dereference_check() message into lockdep Paul E. McKenney
2010-02-25 10:09 ` [tip:core/rcu] rcu: Integrate " tip-bot for Paul E. McKenney
2010-02-23 1:04 ` [PATCH tip/core/rcu 04/21] rcu: disable lockdep checking in RCU list-traversal primitives Paul E. McKenney
2010-02-25 10:10 ` [tip:core/rcu] rcu: Disable " tip-bot for Paul E. McKenney
2010-02-23 1:04 ` [PATCH tip/core/rcu 05/21] net: add checking to rcu_dereference() primitives Paul E. McKenney
2010-02-25 10:10 ` [tip:core/rcu] net: Add " tip-bot for Paul E. McKenney
2010-02-23 1:04 ` [PATCH tip/core/rcu 06/21] sched: use lockdep-based checking on rcu_dereference() Paul E. McKenney
2010-02-25 10:11 ` [tip:core/rcu] sched: Use " tip-bot for Paul E. McKenney
2010-02-25 11:06 ` [tip:core/rcu] sched, cgroups: Fix module export tip-bot for Ingo Molnar
2010-02-23 1:04 ` [PATCH tip/core/rcu 07/21] sched: better name for for_each_domain_rd Paul E. McKenney
2010-02-25 10:11 ` [tip:core/rcu] sched: Better " tip-bot for Paul E. McKenney
2010-02-23 1:04 ` [PATCH tip/core/rcu 08/21] vfs: apply lockdep-based checking to rcu_dereference() uses Paul E. McKenney
2010-02-25 10:11 ` [tip:core/rcu] vfs: Apply " tip-bot for Paul E. McKenney
2010-02-23 1:04 ` [PATCH tip/core/rcu 09/21] vfs: abstract rcu_dereference_check for files-fdtable use Paul E. McKenney
2010-02-25 10:11 ` [tip:core/rcu] vfs: Abstract " tip-bot for Paul E. McKenney
2010-02-23 1:04 ` [PATCH tip/core/rcu 10/21] radix-tree: disable RCU lockdep checking in radix tree Paul E. McKenney
2010-02-25 10:12 ` [tip:core/rcu] radix-tree: Disable " tip-bot for Paul E. McKenney
2010-02-23 1:04 ` [PATCH tip/core/rcu 11/21] idr: apply lockdep-based diagnostics to rcu_dereference() uses Paul E. McKenney
2010-02-25 10:12 ` [tip:core/rcu] idr: Apply " tip-bot for Paul E. McKenney
2010-02-23 1:04 ` [PATCH tip/core/rcu 12/21] security: apply lockdep-based checking " Paul E. McKenney
2010-02-25 10:12 ` [tip:core/rcu] security: Apply " tip-bot for Paul E. McKenney
2010-02-23 1:04 ` [PATCH tip/core/rcu 13/21] rcu: documentation update for CONFIG_PROVE_RCU Paul E. McKenney
2010-02-25 10:12 ` [tip:core/rcu] rcu: Documentation " tip-bot for Paul E. McKenney
2010-02-23 1:04 ` [PATCH tip/core/rcu 14/21] rcu: fix citation of Mathieu's dissertation Paul E. McKenney
2010-02-25 10:13 ` [tip:core/rcu] rcu: Fix " tip-bot for Paul E. McKenney
2010-02-23 1:04 ` [PATCH tip/core/rcu 15/21] rcu: accelerate grace period if last non-dynticked CPU Paul E. McKenney
2010-02-25 10:13 ` [tip:core/rcu] rcu: Accelerate " tip-bot for Paul E. McKenney
2010-02-23 1:05 ` [PATCH tip/core/rcu 16/21] rcu: use canonical URL for Mathieu's dissertation Paul E. McKenney
2010-02-25 10:13 ` [tip:core/rcu] rcu: Use " tip-bot for Paul E. McKenney
2010-02-23 1:05 ` [PATCH tip/core/rcu 17/21] rcu: stop overflowing signed integers Paul E. McKenney
2010-02-25 10:14 ` [tip:core/rcu] rcu: Stop " tip-bot for Paul E. McKenney
2010-02-23 1:05 ` [PATCH tip/core/rcu 18/21] rcu: Convert to raw_spinlocks Paul E. McKenney
2010-02-25 10:14 ` [tip:core/rcu] " tip-bot for Paul E. McKenney
2010-02-23 1:05 ` [PATCH tip/core/rcu 19/21] rcu: fix deadlock in TREE_PREEMPT_RCU CPU stall detection Paul E. McKenney
2010-02-25 10:14 ` [tip:core/rcu] rcu: Fix " tip-bot for Paul E. McKenney
2010-02-23 1:05 ` [PATCH tip/core/rcu 20/21] rcu: fix rcutorture mod_timer argument to delay one jiffy Paul E. McKenney
2010-02-25 10:14 ` [tip:core/rcu] rcu: Fix " tip-bot for Paul E. McKenney
2010-02-23 1:05 ` [PATCH tip/core/rcu 21/21] rcu: add RCU_CPU_STALL_VERBOSE to dump detailed per-task information Paul E. McKenney
2010-02-25 10:15 ` [tip:core/rcu] rcu: Add " tip-bot for Paul E. McKenney
2010-02-23 12:59 ` [PATCH tip/core/rcu 0/21] v6 add lockdep-based diagnostics to rcu_dereference() Arnd Bergmann
2010-02-23 13:15 ` Mathieu Desnoyers
2010-02-23 14:35 ` Paul E. McKenney
2010-02-23 15:54 ` Arnd Bergmann
2010-02-23 16:16 ` Paul E. McKenney
2010-02-23 17:15 ` Arnd Bergmann
2010-02-23 18:01 ` Paul E. McKenney
2010-02-24 20:03 ` [PATCH 00/10] __rcu annotations, first draft Arnd Bergmann
2010-02-24 22:18 ` Paul E. McKenney
2010-02-25 8:37 ` Ingo Molnar
2010-02-24 20:03 ` [PATCH 01/10] rcu: define __rcu address space modifier for sparse Arnd Bergmann
2010-02-24 20:12 ` Mathieu Desnoyers
2010-02-24 20:22 ` Arnd Bergmann
2010-02-24 20:03 ` [PATCH 02/10] rcu: annotated list rcu code Arnd Bergmann
2010-02-24 20:15 ` Mathieu Desnoyers [this message]
2010-02-24 20:32 ` Arnd Bergmann
2010-02-24 20:03 ` [PATCH 03/10] cgroups: __rcu annotations Arnd Bergmann
2010-02-24 20:04 ` [PATCH 04/10] credentials: rcu annotation Arnd Bergmann
2010-02-24 20:04 ` [PATCH 05/10] perf_event: __rcu annotations Arnd Bergmann
2010-02-24 20:04 ` [PATCH 06/10] audit: " Arnd Bergmann
2010-02-24 20:04 ` [PATCH 07/10] module: " Arnd Bergmann
2010-02-24 20:13 ` Alexey Dobriyan
2010-02-24 20:26 ` Arnd Bergmann
2010-02-24 22:17 ` Paul E. McKenney
2010-02-24 23:07 ` Arnd Bergmann
2010-02-24 23:59 ` Paul E. McKenney
2010-02-25 17:06 ` Paul E. McKenney
2010-02-25 18:10 ` Arnd Bergmann
2010-02-25 20:05 ` Paul E. McKenney
2010-02-26 2:12 ` Paul E. McKenney
2010-02-24 20:04 ` [PATCH 08/10] pid: " Arnd Bergmann
2010-02-24 20:04 ` [PATCH 09/10] notifiers: " Arnd Bergmann
2010-02-24 20:04 ` [PATCH 10/10] scheduler: " Arnd Bergmann
2010-02-23 13:28 ` [PATCH tip/core/rcu 0/21] v6 add lockdep-based diagnostics to rcu_dereference() Paul E. McKenney
2010-02-25 10:00 ` Ingo Molnar
2010-02-25 10:01 ` Ingo Molnar
2010-02-25 12:04 ` Ingo Molnar
2010-02-25 18:18 ` Paul E. McKenney
2010-02-25 21:36 ` Paul E. McKenney
2010-02-25 21:22 ` Ingo Molnar
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=20100224201509.GB21067@Krystal \
--to=mathieu.desnoyers@efficios.com \
--cc=Valdis.Kletnieks@vt.edu \
--cc=akpm@linux-foundation.org \
--cc=arnd@arndb.de \
--cc=dhowells@redhat.com \
--cc=dipankar@in.ibm.com \
--cc=dvhltc@us.ibm.com \
--cc=josh@joshtriplett.org \
--cc=laijs@cn.fujitsu.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=niv@us.ibm.com \
--cc=paulmck@linux.vnet.ibm.com \
--cc=peterz@infradead.org \
--cc=rostedt@goodmis.org \
--cc=tglx@linutronix.de \
/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