aboutsummaryrefslogtreecommitdiffstats
path: root/tools/include
diff options
context:
space:
mode:
authorJosh Poimboeuf <jpoimboe@redhat.com>2015-12-18 07:39:16 -0500
committerArnaldo Carvalho de Melo <acme@redhat.com>2016-01-12 10:42:07 -0500
commitd1b39d41ebec2afc761ba6539b77a7fe1669ddae (patch)
tree82b34ae452d5e27737680f879caa9563da605dbe /tools/include
parentb0fb978e97f58ca930f7cafc4ddc264218710765 (diff)
tools: Make list.h self-sufficient
Commit 7f5f873c6a07 ("rculist: Use WRITE_ONCE() when deleting from reader-visible list") added the use of the WRITE_ONCE macro to the kernel version of list.h, which broke the stacktool build because the tools list.h includes the kernel list.h. Avoid this type of situation in the future and make list.h self-sufficient by copying the kernel list.h routines directly into tools list.h. This is a straight copy except for adjustments to the include statements and copying of the tools-specific list routines (list_del_range and list_for_each_from). Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com> Cc: "H. Peter Anvin" <hpa@zytor.com> Cc: Andi Kleen <andi@firstfloor.org> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Andy Lutomirski <luto@kernel.org> Cc: Bernd Petrovitsch <bernd@petrovitsch.priv.at> Cc: Borislav Petkov <bp@alien8.de> Cc: Chris J Arges <chris.j.arges@canonical.com> Cc: Jiri Slaby <jslaby@suse.cz> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Michal Marek <mmarek@suse.cz> Cc: Namhyung Kim <namhyung@gmail.com> Cc: Pedro Alves <palves@redhat.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: live-patching@vger.kernel.org Cc: x86@kernel.org Link: http://lkml.kernel.org/r/59cdc19c6589d1b5ef43d83b0e2d5a4a40301374.1450442274.git.jpoimboe@redhat.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/include')
-rw-r--r--tools/include/linux/list.h753
1 files changed, 747 insertions, 6 deletions
diff --git a/tools/include/linux/list.h b/tools/include/linux/list.h
index a017f1595676..1da423820ad4 100644
--- a/tools/include/linux/list.h
+++ b/tools/include/linux/list.h
@@ -1,11 +1,751 @@
1#include <linux/compiler.h> 1#ifndef __TOOLS_LINUX_LIST_H
2#include <linux/kernel.h> 2#define __TOOLS_LINUX_LIST_H
3
3#include <linux/types.h> 4#include <linux/types.h>
5#include <linux/poison.h>
6#include <linux/kernel.h>
7#include <linux/compiler.h>
8
9/*
10 * Simple doubly linked list implementation.
11 *
12 * Some of the internal functions ("__xxx") are useful when
13 * manipulating whole lists rather than single entries, as
14 * sometimes we already know the next/prev entries and we can
15 * generate better code by using them directly rather than
16 * using the generic single-entry routines.
17 */
18
19#define LIST_HEAD_INIT(name) { &(name), &(name) }
20
21#define LIST_HEAD(name) \
22 struct list_head name = LIST_HEAD_INIT(name)
23
24static inline void INIT_LIST_HEAD(struct list_head *list)
25{
26 list->next = list;
27 list->prev = list;
28}
29
30/*
31 * Insert a new entry between two known consecutive entries.
32 *
33 * This is only for internal list manipulation where we know
34 * the prev/next entries already!
35 */
36#ifndef CONFIG_DEBUG_LIST
37static inline void __list_add(struct list_head *new,
38 struct list_head *prev,
39 struct list_head *next)
40{
41 next->prev = new;
42 new->next = next;
43 new->prev = prev;
44 prev->next = new;
45}
46#else
47extern void __list_add(struct list_head *new,
48 struct list_head *prev,
49 struct list_head *next);
50#endif
51
52/**
53 * list_add - add a new entry
54 * @new: new entry to be added
55 * @head: list head to add it after
56 *
57 * Insert a new entry after the specified head.
58 * This is good for implementing stacks.
59 */
60static inline void list_add(struct list_head *new, struct list_head *head)
61{
62 __list_add(new, head, head->next);
63}
64
65
66/**
67 * list_add_tail - add a new entry
68 * @new: new entry to be added
69 * @head: list head to add it before
70 *
71 * Insert a new entry before the specified head.
72 * This is useful for implementing queues.
73 */
74static inline void list_add_tail(struct list_head *new, struct list_head *head)
75{
76 __list_add(new, head->prev, head);
77}
78
79/*
80 * Delete a list entry by making the prev/next entries
81 * point to each other.
82 *
83 * This is only for internal list manipulation where we know
84 * the prev/next entries already!
85 */
86static inline void __list_del(struct list_head * prev, struct list_head * next)
87{
88 next->prev = prev;
89 WRITE_ONCE(prev->next, next);
90}
91
92/**
93 * list_del - deletes entry from list.
94 * @entry: the element to delete from the list.
95 * Note: list_empty() on entry does not return true after this, the entry is
96 * in an undefined state.
97 */
98#ifndef CONFIG_DEBUG_LIST
99static inline void __list_del_entry(struct list_head *entry)
100{
101 __list_del(entry->prev, entry->next);
102}
103
104static inline void list_del(struct list_head *entry)
105{
106 __list_del(entry->prev, entry->next);
107 entry->next = LIST_POISON1;
108 entry->prev = LIST_POISON2;
109}
110#else
111extern void __list_del_entry(struct list_head *entry);
112extern void list_del(struct list_head *entry);
113#endif
114
115/**
116 * list_replace - replace old entry by new one
117 * @old : the element to be replaced
118 * @new : the new element to insert
119 *
120 * If @old was empty, it will be overwritten.
121 */
122static inline void list_replace(struct list_head *old,
123 struct list_head *new)
124{
125 new->next = old->next;
126 new->next->prev = new;
127 new->prev = old->prev;
128 new->prev->next = new;
129}
130
131static inline void list_replace_init(struct list_head *old,
132 struct list_head *new)
133{
134 list_replace(old, new);
135 INIT_LIST_HEAD(old);
136}
137
138/**
139 * list_del_init - deletes entry from list and reinitialize it.
140 * @entry: the element to delete from the list.
141 */
142static inline void list_del_init(struct list_head *entry)
143{
144 __list_del_entry(entry);
145 INIT_LIST_HEAD(entry);
146}
147
148/**
149 * list_move - delete from one list and add as another's head
150 * @list: the entry to move
151 * @head: the head that will precede our entry
152 */
153static inline void list_move(struct list_head *list, struct list_head *head)
154{
155 __list_del_entry(list);
156 list_add(list, head);
157}
158
159/**
160 * list_move_tail - delete from one list and add as another's tail
161 * @list: the entry to move
162 * @head: the head that will follow our entry
163 */
164static inline void list_move_tail(struct list_head *list,
165 struct list_head *head)
166{
167 __list_del_entry(list);
168 list_add_tail(list, head);
169}
170
171/**
172 * list_is_last - tests whether @list is the last entry in list @head
173 * @list: the entry to test
174 * @head: the head of the list
175 */
176static inline int list_is_last(const struct list_head *list,
177 const struct list_head *head)
178{
179 return list->next == head;
180}
181
182/**
183 * list_empty - tests whether a list is empty
184 * @head: the list to test.
185 */
186static inline int list_empty(const struct list_head *head)
187{
188 return head->next == head;
189}
190
191/**
192 * list_empty_careful - tests whether a list is empty and not being modified
193 * @head: the list to test
194 *
195 * Description:
196 * tests whether a list is empty _and_ checks that no other CPU might be
197 * in the process of modifying either member (next or prev)
198 *
199 * NOTE: using list_empty_careful() without synchronization
200 * can only be safe if the only activity that can happen
201 * to the list entry is list_del_init(). Eg. it cannot be used
202 * if another CPU could re-list_add() it.
203 */
204static inline int list_empty_careful(const struct list_head *head)
205{
206 struct list_head *next = head->next;
207 return (next == head) && (next == head->prev);
208}