diff options
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/bootmem.h | 153 | ||||
| -rw-r--r-- | include/linux/compaction.h | 16 | ||||
| -rw-r--r-- | include/linux/dma-debug.h | 6 | ||||
| -rw-r--r-- | include/linux/fsnotify_backend.h | 118 | ||||
| -rw-r--r-- | include/linux/huge_mm.h | 23 | ||||
| -rw-r--r-- | include/linux/hugetlb.h | 7 | ||||
| -rw-r--r-- | include/linux/init_task.h | 2 | ||||
| -rw-r--r-- | include/linux/ksm.h | 15 | ||||
| -rw-r--r-- | include/linux/memblock.h | 54 | ||||
| -rw-r--r-- | include/linux/mempolicy.h | 32 | ||||
| -rw-r--r-- | include/linux/migrate.h | 6 | ||||
| -rw-r--r-- | include/linux/mm.h | 70 | ||||
| -rw-r--r-- | include/linux/mman.h | 1 | ||||
| -rw-r--r-- | include/linux/mmzone.h | 11 | ||||
| -rw-r--r-- | include/linux/posix_acl.h | 78 | ||||
| -rw-r--r-- | include/linux/rmap.h | 27 | ||||
| -rw-r--r-- | include/linux/sched.h | 12 |
17 files changed, 388 insertions, 243 deletions
diff --git a/include/linux/bootmem.h b/include/linux/bootmem.h index f1f07d31a3af..2fae55def608 100644 --- a/include/linux/bootmem.h +++ b/include/linux/bootmem.h | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | #define _LINUX_BOOTMEM_H | 5 | #define _LINUX_BOOTMEM_H |
| 6 | 6 | ||
| 7 | #include <linux/mmzone.h> | 7 | #include <linux/mmzone.h> |
| 8 | #include <linux/mm_types.h> | ||
| 8 | #include <asm/dma.h> | 9 | #include <asm/dma.h> |
| 9 | 10 | ||
| 10 | /* | 11 | /* |
| @@ -52,7 +53,6 @@ extern void free_bootmem_node(pg_data_t *pgdat, | |||
| 52 | unsigned long size); | 53 | unsigned long size); |
| 53 | extern void free_bootmem(unsigned long physaddr, unsigned long size); | 54 | extern void free_bootmem(unsigned long physaddr, unsigned long size); |
| 54 | extern void free_bootmem_late(unsigned long physaddr, unsigned long size); | 55 | extern void free_bootmem_late(unsigned long physaddr, unsigned long size); |
| 55 | extern void __free_pages_bootmem(struct page *page, unsigned int order); | ||
| 56 | 56 | ||
| 57 | /* | 57 | /* |
| 58 | * Flags for reserve_bootmem (also if CONFIG_HAVE_ARCH_BOOTMEM_NODE, | 58 | * Flags for reserve_bootmem (also if CONFIG_HAVE_ARCH_BOOTMEM_NODE, |
| @@ -142,6 +142,157 @@ extern void *__alloc_bootmem_low_node(pg_data_t *pgdat, | |||
| 142 | #define alloc_bootmem_low_pages_node(pgdat, x) \ | 142 | #define alloc_bootmem_low_pages_node(pgdat, x) \ |
| 143 | __alloc_bootmem_low_node(pgdat, x, PAGE_SIZE, 0) | 143 | __alloc_bootmem_low_node(pgdat, x, PAGE_SIZE, 0) |
| 144 | 144 | ||
| 145 | |||
| 146 | #if defined(CONFIG_HAVE_MEMBLOCK) && defined(CONFIG_NO_BOOTMEM) | ||
| 147 | |||
| 148 | /* FIXME: use MEMBLOCK_ALLOC_* variants here */ | ||
| 149 | #define BOOTMEM_ALLOC_ACCESSIBLE 0 | ||
| 150 | #define BOOTMEM_ALLOC_ANYWHERE (~(phys_addr_t)0) | ||
| 151 | |||
| 152 | /* FIXME: Move to memblock.h at a point where we remove nobootmem.c */ | ||
| 153 | void *memblock_virt_alloc_try_nid_nopanic(phys_addr_t size, | ||
| 154 | phys_addr_t align, phys_addr_t min_addr, | ||
| 155 | phys_addr_t max_addr, int nid); | ||
| 156 | void *memblock_virt_alloc_try_nid(phys_addr_t size, phys_addr_t align, | ||
| 157 | phys_addr_t min_addr, phys_addr_t max_addr, int nid); | ||
| 158 | void __memblock_free_early(phys_addr_t base, phys_addr_t size); | ||
| 159 | void __memblock_free_late(phys_addr_t base, phys_addr_t size); | ||
| 160 | |||
| 161 | static inline void * __init memblock_virt_alloc( | ||
| 162 | phys_addr_t size, phys_addr_t align) | ||
| 163 | { | ||
| 164 | return memblock_virt_alloc_try_nid(size, align, BOOTMEM_LOW_LIMIT, | ||
| 165 | BOOTMEM_ALLOC_ACCESSIBLE, | ||
| 166 | NUMA_NO_NODE); | ||
| 167 | } | ||
| 168 | |||
| 169 | static inline void * __init memblock_virt_alloc_nopanic( | ||
| 170 | phys_addr_t size, phys_addr_t align) | ||
| 171 | { | ||
| 172 | return memblock_virt_alloc_try_nid_nopanic(size, align, | ||
| 173 | BOOTMEM_LOW_LIMIT, | ||
| 174 | BOOTMEM_ALLOC_ACCESSIBLE, | ||
| 175 | NUMA_NO_NODE); | ||
| 176 | } | ||
| 177 | |||
| 178 | static inline void * __init memblock_virt_alloc_from_nopanic( | ||
| 179 | phys_addr_t size, phys_addr_t align, phys_addr_t min_addr) | ||
| 180 | { | ||
| 181 | return memblock_virt_alloc_try_nid_nopanic(size, align, min_addr, | ||
| 182 | BOOTMEM_ALLOC_ACCESSIBLE, | ||
| 183 | NUMA_NO_NODE); | ||
| 184 | } | ||
| 185 | |||
| 186 | static inline void * __init memblock_virt_alloc_node( | ||
| 187 | phys_addr_t size, int nid) | ||
| 188 | { | ||
| 189 | return memblock_virt_alloc_try_nid(size, 0, BOOTMEM_LOW_LIMIT, | ||
| 190 | BOOTMEM_ALLOC_ACCESSIBLE, nid); | ||
| 191 | } | ||
| 192 | |||
| 193 | static inline void * __init memblock_virt_alloc_node_nopanic( | ||
| 194 | phys_addr_t size, int nid) | ||
| 195 | { | ||
| 196 | return memblock_virt_alloc_try_nid_nopanic(size, 0, BOOTMEM_LOW_LIMIT, | ||
| 197 | BOOTMEM_ALLOC_ACCESSIBLE, | ||
| 198 | nid); | ||
| 199 | } | ||
| 200 | |||
| 201 | static inline void __init memblock_free_early( | ||
| 202 | phys_addr_t base, phys_addr_t size) | ||
| 203 | { | ||
| 204 | __memblock_free_early(base, size); | ||
| 205 | } | ||
| 206 | |||
| 207 | static inline void __init memblock_free_early_nid( | ||
| 208 | phys_addr_t base, phys_addr_t size, int nid) | ||
| 209 | { | ||
| 210 | __memblock_free_early(base, size); | ||
| 211 | } | ||
| 212 | |||
| 213 | static inline void __init memblock_free_late( | ||
| 214 | phys_addr_t base, phys_addr_t size) | ||
| 215 | { | ||
| 216 | __memblock_free_late(base, size); | ||
| 217 | } | ||
| 218 | |||
| 219 | #else | ||
| 220 | |||
| 221 | #define BOOTMEM_ALLOC_ACCESSIBLE 0 | ||
| 222 | |||
| 223 | |||
| 224 | /* Fall back to all the existing bootmem APIs */ | ||
| 225 | static inline void * __init memblock_virt_alloc( | ||
| 226 | phys_addr_t size, phys_addr_t align) | ||
| 227 | { | ||
| 228 | if (!align) | ||
| 229 | align = SMP_CACHE_BYTES; | ||
| 230 | return __alloc_bootmem(size, align, BOOTMEM_LOW_LIMIT); | ||
| 231 | } | ||
| 232 | |||
| 233 | static inline void * __init memblock_virt_alloc_nopanic( | ||
| 234 | phys_addr_t size, phys_addr_t align) | ||
| 235 | { | ||
| 236 | if (!align) | ||
| 237 | align = SMP_CACHE_BYTES; | ||
| 238 | return __alloc_bootmem_nopanic(size, align, BOOTMEM_LOW_LIMIT); | ||
| 239 | } | ||
| 240 | |||
| 241 | static inline void * __init memblock_virt_alloc_from_nopanic( | ||
| 242 | phys_addr_t size, phys_addr_t align, phys_addr_t min_addr) | ||
| 243 | { | ||
| 244 | return __alloc_bootmem_nopanic(size, align, min_addr); | ||
| 245 | } | ||
| 246 | |||
| 247 | static inline void * __init memblock_virt_alloc_node( | ||
| 248 | phys_addr_t size, int nid) | ||
| 249 | { | ||
| 250 | return __alloc_bootmem_node(NODE_DATA(nid), size, SMP_CACHE_BYTES, | ||
| 251 | BOOTMEM_LOW_LIMIT); | ||
| 252 | } | ||
| 253 | |||
| 254 | static inline void * __init memblock_virt_alloc_node_nopanic( | ||
| 255 | phys_addr_t size, int nid) | ||
| 256 | { | ||
| 257 | return __alloc_bootmem_node_nopanic(NODE_DATA(nid), size, | ||
| 258 | SMP_CACHE_BYTES, | ||
| 259 | BOOTMEM_LOW_LIMIT); | ||
| 260 | } | ||
| 261 | |||
| 262 | static inline void * __init memblock_virt_alloc_try_nid(phys_addr_t size, | ||
| 263 | phys_addr_t align, phys_addr_t min_addr, phys_addr_t max_addr, int nid) | ||
| 264 | { | ||
| 265 | return __alloc_bootmem_node_high(NODE_DATA(nid), size, align, | ||
| 266 | min_addr); | ||
| 267 | } | ||
| 268 | |||
| 269 | static inline void * __init memblock_virt_alloc_try_nid_nopanic( | ||
| 270 | phys_addr_t size, phys_addr_t align, | ||
| 271 | phys_addr_t min_addr, phys_addr_t max_addr, int nid) | ||
| 272 | { | ||
| 273 | return ___alloc_bootmem_node_nopanic(NODE_DATA(nid), size, align, | ||
| 274 | min_addr, max_addr); | ||
| 275 | } | ||
| 276 | |||
| 277 | static inline void __init memblock_free_early( | ||
| 278 | phys_addr_t base, phys_addr_t size) | ||
| 279 | { | ||
| 280 | free_bootmem(base, size); | ||
| 281 | } | ||
| 282 | |||
| 283 | static inline void __init memblock_free_early_nid( | ||
| 284 | phys_addr_t base, phys_addr_t size, int nid) | ||
| 285 | { | ||
| 286 | free_bootmem_node(NODE_DATA(nid), base, size); | ||
| 287 | } | ||
| 288 | |||
| 289 | static inline void __init memblock_free_late( | ||
| 290 | phys_addr_t base, phys_addr_t size) | ||
| 291 | { | ||
| 292 | free_bootmem_late(base, size); | ||
| 293 | } | ||
| 294 | #endif /* defined(CONFIG_HAVE_MEMBLOCK) && defined(CONFIG_NO_BOOTMEM) */ | ||
| 295 | |||
| 145 | #ifdef CONFIG_HAVE_ARCH_ALLOC_REMAP | 296 | #ifdef CONFIG_HAVE_ARCH_ALLOC_REMAP |
| 146 | extern void *alloc_remap(int nid, unsigned long size); | 297 | extern void *alloc_remap(int nid, unsigned long size); |
| 147 | #else | 298 | #else |
diff --git a/include/linux/compaction.h b/include/linux/compaction.h index 091d72e70d8a..7e1c76e3cd68 100644 --- a/include/linux/compaction.h +++ b/include/linux/compaction.h | |||
| @@ -62,6 +62,22 @@ static inline bool compaction_deferred(struct zone *zone, int order) | |||
| 62 | return zone->compact_considered < defer_limit; | 62 | return zone->compact_considered < defer_limit; |
| 63 | } | 63 | } |
| 64 | 64 | ||
| 65 | /* | ||
| 66 | * Update defer tracking counters after successful compaction of given order, | ||
| 67 | * which means an allocation either succeeded (alloc_success == true) or is | ||
| 68 | * expected to succeed. | ||
| 69 | */ | ||
| 70 | static inline void compaction_defer_reset(struct zone *zone, int order, | ||
| 71 | bool alloc_success) | ||
| 72 | { | ||
| 73 | if (alloc_success) { | ||
| 74 | zone->compact_considered = 0; | ||
| 75 | zone->compact_defer_shift = 0; | ||
| 76 | } | ||
| 77 | if (order >= zone->compact_order_failed) | ||
| 78 | zone->compact_order_failed = order + 1; | ||
| 79 | } | ||
| 80 | |||
| 65 | /* Returns true if restarting compaction after many failures */ | 81 | /* Returns true if restarting compaction after many failures */ |
| 66 | static inline bool compaction_restarting(struct zone *zone, int order) | 82 | static inline bool compaction_restarting(struct zone *zone, int order) |
| 67 | { | 83 | { |
diff --git a/include/linux/dma-debug.h b/include/linux/dma-debug.h index fc0e34ce038f..fe8cb610deac 100644 --- a/include/linux/dma-debug.h +++ b/include/linux/dma-debug.h | |||
| @@ -85,6 +85,8 @@ extern void debug_dma_sync_sg_for_device(struct device *dev, | |||
| 85 | 85 | ||
| 86 | extern void debug_dma_dump_mappings(struct device *dev); | 86 | extern void debug_dma_dump_mappings(struct device *dev); |
| 87 | 87 | ||
| 88 | extern void debug_dma_assert_idle(struct page *page); | ||
| 89 | |||
| 88 | #else /* CONFIG_DMA_API_DEBUG */ | 90 | #else /* CONFIG_DMA_API_DEBUG */ |
| 89 | 91 | ||
| 90 | static inline void dma_debug_add_bus(struct bus_type *bus) | 92 | static inline void dma_debug_add_bus(struct bus_type *bus) |
| @@ -183,6 +185,10 @@ static inline void debug_dma_dump_mappings(struct device *dev) | |||
| 183 | { | 185 | { |
| 184 | } | 186 | } |
| 185 | 187 | ||
| 188 | static inline void debug_dma_assert_idle(struct page *page) | ||
| 189 | { | ||
| 190 | } | ||
| 191 | |||
| 186 | #endif /* CONFIG_DMA_API_DEBUG */ | 192 | #endif /* CONFIG_DMA_API_DEBUG */ |
| 187 | 193 | ||
| 188 | #endif /* __DMA_DEBUG_H */ | 194 | #endif /* __DMA_DEBUG_H */ |
diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h index 4b2ee8d12f5e..7d8d5e608594 100644 --- a/include/linux/fsnotify_backend.h +++ b/include/linux/fsnotify_backend.h | |||
| @@ -15,7 +15,6 @@ | |||
| 15 | #include <linux/path.h> /* struct path */ | 15 | #include <linux/path.h> /* struct path */ |
| 16 | #include <linux/spinlock.h> | 16 | #include <linux/spinlock.h> |
| 17 | #include <linux/types.h> | 17 | #include <linux/types.h> |
| 18 | |||
| 19 | #include <linux/atomic.h> | 18 | #include <linux/atomic.h> |
| 20 | 19 | ||
| 21 | /* | 20 | /* |
| @@ -79,6 +78,7 @@ struct fsnotify_group; | |||
| 79 | struct fsnotify_event; | 78 | struct fsnotify_event; |
| 80 | struct fsnotify_mark; | 79 | struct fsnotify_mark; |
| 81 | struct fsnotify_event_private_data; | 80 | struct fsnotify_event_private_data; |
| 81 | struct fsnotify_fname; | ||
| 82 | 82 | ||
| 83 | /* | 83 | /* |
| 84 | * Each group much define these ops. The fsnotify infrastructure will call | 84 | * Each group much define these ops. The fsnotify infrastructure will call |
| @@ -94,17 +94,27 @@ struct fsnotify_event_private_data; | |||
| 94 | * userspace messages that marks have been removed. | 94 | * userspace messages that marks have been removed. |
| 95 | */ | 95 | */ |
| 96 | struct fsnotify_ops { | 96 | struct fsnotify_ops { |
| 97 | bool (*should_send_event)(struct fsnotify_group *group, struct inode *inode, | ||
| 98 | struct fsnotify_mark *inode_mark, | ||
| 99 | struct fsnotify_mark *vfsmount_mark, | ||
| 100 | __u32 mask, void *data, int data_type); | ||
| 101 | int (*handle_event)(struct fsnotify_group *group, | 97 | int (*handle_event)(struct fsnotify_group *group, |
| 98 | struct inode *inode, | ||
| 102 | struct fsnotify_mark *inode_mark, | 99 | struct fsnotify_mark *inode_mark, |
| 103 | struct fsnotify_mark *vfsmount_mark, | 100 | struct fsnotify_mark *vfsmount_mark, |
| 104 | struct fsnotify_event *event); | 101 | u32 mask, void *data, int data_type, |
| 102 | const unsigned char *file_name); | ||
| 105 | void (*free_group_priv)(struct fsnotify_group *group); | 103 | void (*free_group_priv)(struct fsnotify_group *group); |
| 106 | void (*freeing_mark)(struct fsnotify_mark *mark, struct fsnotify_group *group); | 104 | void (*freeing_mark)(struct fsnotify_mark *mark, struct fsnotify_group *group); |
| 107 | void (*free_event_priv)(struct fsnotify_event_private_data *priv); | 105 | void (*free_event)(struct fsnotify_event *event); |
| 106 | }; | ||
| 107 | |||
| 108 | /* | ||
| 109 | * all of the information about the original object we want to now send to | ||
| 110 | * a group. If you want to carry more info from the accessing task to the | ||
| 111 | * listener this structure is where you need to be adding fields. | ||
| 112 | */ | ||
| 113 | struct fsnotify_event { | ||
| 114 | struct list_head list; | ||
| 115 | /* inode may ONLY be dereferenced during handle_event(). */ | ||
| 116 | struct inode *inode; /* either the inode the event happened to or its parent */ | ||
| 117 | u32 mask; /* the type of access, bitwise OR for FS_* event types */ | ||
| 108 | }; | 118 | }; |
| 109 | 119 | ||
| 110 | /* | 120 | /* |
| @@ -148,7 +158,11 @@ struct fsnotify_group { | |||
| 148 | * a group */ | 158 | * a group */ |
| 149 | struct list_head marks_list; /* all inode marks for this group */ | 159 | struct list_head marks_list; /* all inode marks for this group */ |
| 150 | 160 | ||
| 151 | struct fasync_struct *fsn_fa; /* async notification */ | 161 | struct fasync_struct *fsn_fa; /* async notification */ |
| 162 | |||
| 163 | struct fsnotify_event overflow_event; /* Event we queue when the | ||
| 164 | * notification list is too | ||
| 165 | * full */ | ||
| 152 | 166 | ||
| 153 | /* groups can define private fields here or use the void *private */ | 167 | /* groups can define private fields here or use the void *private */ |
| 154 | union { | 168 | union { |
| @@ -177,76 +191,10 @@ struct fsnotify_group { | |||
| 177 | }; | 191 | }; |
| 178 | }; | 192 | }; |
| 179 | 193 | ||
| 180 | /* | ||
| 181 | * A single event can be queued in multiple group->notification_lists. | ||
| 182 | * | ||
| 183 | * each group->notification_list will point to an event_holder which in turns points | ||
| 184 | * to the actual event that needs to be sent to userspace. | ||
| 185 | * | ||
| 186 | * Seemed cheaper to create a refcnt'd event and a small holder for every group | ||
| 187 | * than create a different event for every group | ||
| 188 | * | ||
| 189 | */ | ||
| 190 | struct fsnotify_event_holder { | ||
| 191 | struct fsnotify_event *event; | ||
| 192 | struct list_head event_list; | ||
| 193 | }; | ||
| 194 | |||
| 195 | /* | ||
| 196 | * Inotify needs to tack data onto an event. This struct lets us later find the | ||
| 197 | * correct private data of the correct group. | ||
| 198 | */ | ||
| 199 | struct fsnotify_event_private_data { | ||
| 200 | struct fsnotify_group *group; | ||
| 201 | struct list_head event_list; | ||
| 202 | }; | ||
| 203 | |||
| 204 | /* | ||
| 205 | * all of the information about the original object we want to now send to | ||
| 206 | * a group. If you want to carry more info from the accessing task to the | ||
| 207 | * listener this structure is where you need to be adding fields. | ||
| 208 | */ | ||
| 209 | struct fsnotify_event { | ||
| 210 | /* | ||
| 211 | * If we create an event we are also likely going to need a holder | ||
| 212 | * to link to a group. So embed one holder in the event. Means only | ||
| 213 | * one allocation for the common case where we only have one group | ||
| 214 | */ | ||
| 215 | struct fsnotify_event_holder holder; | ||
| 216 | spinlock_t lock; /* protection for the associated event_holder and private_list */ | ||
| 217 | /* to_tell may ONLY be dereferenced during handle_event(). */ | ||
| 218 | struct inode *to_tell; /* either the inode the event happened to or its parent */ | ||
| 219 | /* | ||
| 220 | * depending on the event type we should have either a path or inode | ||
| 221 | * We hold a reference on path, but NOT on inode. Since we have the ref on | ||
| 222 | * the path, it may be dereferenced at any point during this object's | ||
| 223 | * lifetime. That reference is dropped when this object's refcnt hits | ||
| 224 | * 0. If this event contains an inode instead of a path, the inode may | ||
| 225 | * ONLY be used during handle_event(). | ||
| 226 | */ | ||
| 227 | union { | ||
| 228 | struct path path; | ||
| 229 | struct inode *inode; | ||
| 230 | }; | ||
| 231 | /* when calling fsnotify tell it if the data is a path or inode */ | 194 | /* when calling fsnotify tell it if the data is a path or inode */ |
| 232 | #define FSNOTIFY_EVENT_NONE 0 | 195 | #define FSNOTIFY_EVENT_NONE 0 |
| 233 | #define FSNOTIFY_EVENT_PATH 1 | 196 | #define FSNOTIFY_EVENT_PATH 1 |
| 234 | #define FSNOTIFY_EVENT_INODE 2 | 197 | #define FSNOTIFY_EVENT_INODE 2 |
| 235 | int data_type; /* which of the above union we have */ | ||
| 236 | atomic_t refcnt; /* how many groups still are using/need to send this event */ | ||
| 237 | __u32 mask; /* the type of access, bitwise OR for FS_* event types */ | ||
| 238 | |||
| 239 | u32 sync_cookie; /* used to corrolate events, namely inotify mv events */ | ||
| 240 | const unsigned char *file_name; | ||
| 241 | size_t name_len; | ||
| 242 | struct pid *tgid; | ||
| 243 | |||
| 244 | #ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS | ||
| 245 | __u32 response; /* userspace answer to question */ | ||
| 246 | #endif /* CONFIG_FANOTIFY_ACCESS_PERMISSIONS */ | ||
| 247 | |||
| 248 | struct list_head private_data_list; /* groups can store private data here */ | ||
| 249 | }; | ||
| 250 | 198 | ||
| 251 | /* | 199 | /* |
| 252 | * Inode specific fields in an fsnotify_mark | 200 | * Inode specific fields in an fsnotify_mark |
| @@ -370,17 +318,12 @@ extern void fsnotify_put_group(struct fsnotify_group *group); | |||
| 370 | extern void fsnotify_destroy_group(struct fsnotify_group *group); | 318 | extern void fsnotify_destroy_group(struct fsnotify_group *group); |
| 371 | /* fasync handler function */ | 319 | /* fasync handler function */ |
| 372 | extern int fsnotify_fasync(int fd, struct file *file, int on); | 320 | extern int fsnotify_fasync(int fd, struct file *file, int on); |
| 373 | /* take a reference to an event */ | 321 | /* Free event from memory */ |
| 374 | extern void fsnotify_get_event(struct fsnotify_event *event); | 322 | extern void fsnotify_destroy_event(struct fsnotify_group *group, |
| 375 | extern void fsnotify_put_event(struct fsnotify_event *event); | 323 | struct fsnotify_event *event); |
| 376 | /* find private data previously attached to an event and unlink it */ | ||
| 377 | extern struct fsnotify_event_private_data *fsnotify_remove_priv_from_event(struct fsnotify_group *group, | ||
| 378 | struct fsnotify_event *event); | ||
| 379 | |||
| 380 | /* attach the event to the group notification queue */ | 324 | /* attach the event to the group notification queue */ |
| 381 | extern struct fsnotify_event *fsnotify_add_notify_event(struct fsnotify_group *group, | 325 | extern struct fsnotify_event *fsnotify_add_notify_event(struct fsnotify_group *group, |
| 382 | struct fsnotify_event *event, | 326 | struct fsnotify_event *event, |
| 383 | struct fsnotify_event_private_data *priv, | ||
| 384 | struct fsnotify_event *(*merge)(struct list_head *, | 327 | struct fsnotify_event *(*merge)(struct list_head *, |
| 385 | struct fsnotify_event *)); | 328 | struct fsnotify_event *)); |
| 386 | /* true if the group notification queue is empty */ | 329 | /* true if the group notification queue is empty */ |
| @@ -430,15 +373,8 @@ extern void fsnotify_put_mark(struct fsnotify_mark *mark); | |||
| 430 | extern void fsnotify_unmount_inodes(struct list_head *list); | 373 | extern void fsnotify_unmount_inodes(struct list_head *list); |
| 431 | 374 | ||
| 432 | /* put here because inotify does some weird stuff when destroying watches */ | 375 | /* put here because inotify does some weird stuff when destroying watches */ |
| 433 | extern struct fsnotify_event *fsnotify_create_event(struct inode *to_tell, __u32 mask, | 376 | extern void fsnotify_init_event(struct fsnotify_event *event, |
| 434 | void *data, int data_is, | 377 | struct inode *to_tell, u32 mask); |
| 435 | const unsigned char *name, | ||
| 436 | u32 cookie, gfp_t gfp); | ||
| 437 | |||
| 438 | /* fanotify likes to change events after they are on lists... */ | ||
| 439 | extern struct fsnotify_event *fsnotify_clone_event(struct fsnotify_event *old_event); | ||
| 440 | extern int fsnotify_replace_event(struct fsnotify_event_holder *old_holder, | ||
| 441 | struct fsnotify_event *new_event); | ||
| 442 | 378 | ||
| 443 | #else | 379 | #else |
| 444 | 380 | ||
diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h index 91672e2deec3..db512014e061 100644 --- a/include/linux/huge_mm.h +++ b/include/linux/huge_mm.h | |||
| @@ -157,6 +157,26 @@ static inline int hpage_nr_pages(struct page *page) | |||
| 157 | return HPAGE_PMD_NR; | 157 | return HPAGE_PMD_NR; |
| 158 | return 1; | 158 | return 1; |
| 159 | } | 159 | } |
| 160 | /* | ||
| 161 | * compound_trans_head() should be used instead of compound_head(), | ||
| 162 | * whenever the "page" passed as parameter could be the tail of a | ||
| 163 | * transparent hugepage that could be undergoing a | ||
| 164 | * __split_huge_page_refcount(). The page structure layout often | ||
| 165 | * changes across releases and it makes extensive use of unions. So if | ||
| 166 | * the page structure layout will change in a way that | ||
| 167 | * page->first_page gets clobbered by __split_huge_page_refcount, the | ||
| 168 | * implementation making use of smp_rmb() will be required. | ||
| 169 | * | ||
| 170 | * Currently we define compound_trans_head as compound_head, because | ||
| 171 | * page->private is in the same union with page->first_page, and | ||
| 172 | * page->private isn't clobbered. However this also means we're | ||
| 173 | * currently leaving dirt into the page->private field of anonymous | ||
| 174 | * pages resulting from a THP split, instead of setting page->private | ||
| 175 | * to zero like for every other page that has PG_private not set. But | ||
| 176 | * anonymous pages don't use page->private so this is not a problem. | ||
| 177 | */ | ||
| 178 | #if 0 | ||
| 179 | /* This will be needed if page->private will be clobbered in split_huge_page */ | ||
| 160 | static inline struct page *compound_trans_head(struct page *page) | 180 | static inline struct page *compound_trans_head(struct page *page) |
| 161 | { | 181 | { |
| 162 | if (PageTail(page)) { | 182 | if (PageTail(page)) { |
| @@ -174,6 +194,9 @@ static inline struct page *compound_trans_head(struct page *page) | |||
| 174 | } | 194 | } |
| 175 | return page; | 195 | return page; |
| 176 | } | 196 | } |
| 197 | #else | ||
| 198 | #define compound_trans_head(page) compound_head(page) | ||
| 199 | #endif | ||
| 177 | 200 | ||
| 178 | extern int do_huge_pmd_numa_page(struct mm_struct *mm, struct vm_area_struct *vma, | 201 | extern int do_huge_pmd_numa_page(struct mm_struct *mm, struct vm_area_struct *vma, |
| 179 | unsigned long addr, pmd_t pmd, pmd_t *pmdp); | 202 | unsigned long addr, pmd_t pmd, pmd_t *pmdp); |
diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h index bd7e98752222..d01cc972a1d9 100644 --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h | |||
| @@ -31,7 +31,6 @@ struct hugepage_subpool *hugepage_new_subpool(long nr_blocks); | |||
| 31 | void hugepage_put_subpool(struct hugepage_subpool *spool); | 31 | void hugepage_put_subpool(struct hugepage_subpool *spool); |
| 32 | 32 | ||
| 33 | int PageHuge(struct page *page); | 33 | int PageHuge(struct page *page); |
| 34 | int PageHeadHuge(struct page *page_head); | ||
| 35 | 34 | ||
| 36 | void reset_vma_resv_huge_pages(struct vm_area_struct *vma); | 35 | void reset_vma_resv_huge_pages(struct vm_area_struct *vma); |
| 37 | int hugetlb_sysctl_handler(struct ctl_table *, int, void __user *, size_t *, loff_t *); | 36 | int hugetlb_sysctl_handler(struct ctl_table *, int, void __user *, size_t *, loff_t *); |
| @@ -104,11 +103,6 @@ static inline int PageHuge(struct page *page) | |||
| 104 | return 0; | 103 | return 0; |
| 105 | } | 104 | } |
| 106 | 105 | ||
| 107 | static inline int PageHeadHuge(struct page *page_head) | ||
| 108 | { | ||
| 109 | return 0; | ||
| 110 | } | ||
| 111 | |||
| 112 | static inline void reset_vma_resv_huge_pages(struct vm_area_struct *vma) | 106 | static inline void reset_vma_resv_huge_pages(struct vm_area_struct *vma) |
| 113 | { | 107 | { |
| 114 | } | 108 | } |
| @@ -360,6 +354,7 @@ static inline pte_t arch_make_huge_pte(pte_t entry, struct vm_area_struct *vma, | |||
| 360 | 354 | ||
| 361 | static inline struct hstate *page_hstate(struct page *page) | 355 | static inline struct hstate *page_hstate(struct page *page) |
| 362 | { | 356 | { |
| 357 | VM_BUG_ON(!PageHuge(page)); | ||
| 363 | return size_to_hstate(PAGE_SIZE << compound_order(page)); | 358 | return size_to_hstate(PAGE_SIZE << compound_order(page)); |
| 364 | } | 359 | } |
| 365 | 360 | ||
diff --git a/include/linux/init_task.h b/include/linux/init_task.h index f0e52383a001..1516a8ff8f92 100644 --- a/include/linux/init_task.h +++ b/include/linux/init_task.h | |||
| @@ -41,6 +41,7 @@ extern struct fs_struct init_fs; | |||
| 41 | 41 | ||
| 42 | #define INIT_SIGNALS(sig) { \ | 42 | #define INIT_SIGNALS(sig) { \ |
| 43 | .nr_threads = 1, \ | 43 | .nr_threads = 1, \ |
| 44 | .thread_head = LIST_HEAD_INIT(init_task.thread_node), \ | ||
| 44 | .wait_chldexit = __WAIT_QUEUE_HEAD_INITIALIZER(sig.wait_chldexit),\ | 45 | .wait_chldexit = __WAIT_QUEUE_HEAD_INITIALIZER(sig.wait_chldexit),\ |
| 45 | .shared_pending = { \ | 46 | .shared_pending = { \ |
| 46 | .list = LIST_HEAD_INIT(sig.shared_pending.list), \ | 47 | .list = LIST_HEAD_INIT(sig.shared_pending.list), \ |
| @@ -222,6 +223,7 @@ extern struct task_group root_task_group; | |||
| 222 | [PIDTYPE_SID] = INIT_PID_LINK(PIDTYPE_SID), \ | 223 | [PIDTYPE_SID] = INIT_PID_LINK(PIDTYPE_SID), \ |
| 223 | }, \ | 224 | }, \ |
| 224 | .thread_group = LIST_HEAD_INIT(tsk.thread_group), \ | 225 | .thread_group = LIST_HEAD_INIT(tsk.thread_group), \ |
| 226 | .thread_node = LIST_HEAD_INIT(init_signals.thread_head), \ | ||
| 225 | INIT_IDS \ | 227 | INIT_IDS \ |
| 226 | INIT_PERF_EVENTS(tsk) \ | 228 | INIT_PERF_EVENTS(tsk) \ |
| 227 | INIT_TRACE_IRQFLAGS \ | 229 | INIT_TRACE_IRQFLAGS \ |
diff --git a/include/linux/ksm.h b/include/linux/ksm.h index 45c9b6a17bcb..3be6bb18562d 100644 --- a/include/linux/ksm.h +++ b/include/linux/ksm.h | |||
| @@ -73,11 +73,7 @@ static inline void set_page_stable_node(struct page *page, | |||
| 73 | struct page *ksm_might_need_to_copy(struct page *page, | 73 | struct page *ksm_might_need_to_copy(struct page *page, |
| 74 | struct vm_area_struct *vma, unsigned long address); | 74 | struct vm_area_struct *vma, unsigned long address); |
| 75 | 75 | ||
| 76 | int page_referenced_ksm(struct page *page, | 76 | int rmap_walk_ksm(struct page *page, struct rmap_walk_control *rwc); |
| 77 | struct mem_cgroup *memcg, unsigned long *vm_flags); | ||
| 78 | int try_to_unmap_ksm(struct page *page, enum ttu_flags flags); | ||
| 79 | int rmap_walk_ksm(struct page *page, int (*rmap_one)(struct page *, | ||
| 80 | struct vm_area_struct *, unsigned long, void *), void *arg); | ||
| 81 | void ksm_migrate_page(struct page *newpage, struct page *oldpage); | 77 | void ksm_migrate_page(struct page *newpage, struct page *oldpage); |
| 82 | 78 | ||
| 83 | #else /* !CONFIG_KSM */ | 79 | #else /* !CONFIG_KSM */ |
| @@ -115,13 +111,8 @@ static inline int page_referenced_ksm(struct page *page, | |||
| 115 | return 0; | 111 | return 0; |
| 116 | } | 112 | } |
| 117 | 113 | ||
| 118 | static inline int try_to_unmap_ksm(struct page *page, enum ttu_flags flags) | 114 | static inline int rmap_walk_ksm(struct page *page, |
| 119 | { | 115 | struct rmap_walk_control *rwc) |
| 120 | return 0; | ||
| 121 | } | ||
| 122 | |||
| 123 | static inline int rmap_walk_ksm(struct page *page, int (*rmap_one)(struct page*, | ||
| 124 | struct vm_area_struct *, unsigned long, void *), void *arg) | ||
| 125 | { | 116 | { |
| 126 | return 0; | 117 | return 0; |
| 127 | } | 118 | } |
diff --git a/include/linux/memblock.h b/include/linux/memblock.h index 77c60e52939d..cd0274bebd4c 100644 --- a/include/linux/memblock.h +++ b/include/linux/memblock.h | |||
| @@ -19,9 +19,13 @@ | |||
| 19 | 19 | ||
| 20 | #define INIT_MEMBLOCK_REGIONS 128 | 20 | #define INIT_MEMBLOCK_REGIONS 128 |
| 21 | 21 | ||
| 22 | /* Definition of memblock flags. */ | ||
| 23 | #define MEMBLOCK_HOTPLUG 0x1 /* hotpluggable region */ | ||
| 24 | |||
| 22 | struct memblock_region { | 25 | struct memblock_region { |
| 23 | phys_addr_t base; | 26 | phys_addr_t base; |
| 24 | phys_addr_t size; | 27 | phys_addr_t size; |
| 28 | unsigned long flags; | ||
| 25 | #ifdef CONFIG_HAVE_MEMBLOCK_NODE_MAP | 29 | #ifdef CONFIG_HAVE_MEMBLOCK_NODE_MAP |
| 26 | int nid; | 30 | int nid; |
| 27 | #endif | 31 | #endif |
| @@ -43,12 +47,17 @@ struct memblock { | |||
| 43 | 47 | ||
| 44 | extern struct memblock memblock; | 48 | extern struct memblock memblock; |
| 45 | extern int memblock_debug; | 49 | extern int memblock_debug; |
| 50 | #ifdef CONFIG_MOVABLE_NODE | ||
| 51 | /* If movable_node boot option specified */ | ||
| 52 | extern bool movable_node_enabled; | ||
| 53 | #endif /* CONFIG_MOVABLE_NODE */ | ||
| 46 | 54 | ||
| 47 | #define memblock_dbg(fmt, ...) \ | 55 | #define memblock_dbg(fmt, ...) \ |
| 48 | if (memblock_debug) printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__) | 56 | if (memblock_debug) printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__) |
| 49 | 57 | ||
| 50 | phys_addr_t memblock_find_in_range_node(phys_addr_t start, phys_addr_t end, | 58 | phys_addr_t memblock_find_in_range_node(phys_addr_t size, phys_addr_t align, |
| 51 | phys_addr_t size, phys_addr_t align, int nid); | 59 | phys_addr_t start, phys_addr_t end, |
| 60 | int nid); | ||
| 52 | phys_addr_t memblock_find_in_range(phys_addr_t start, phys_addr_t end, | 61 | phys_addr_t memblock_find_in_range(phys_addr_t start, phys_addr_t end, |
| 53 | phys_addr_t size, phys_addr_t align); | 62 | phys_addr_t size, phys_addr_t align); |
| 54 | phys_addr_t get_allocated_memblock_reserved_regions_info(phys_addr_t *addr); | 63 | phys_addr_t get_allocated_memblock_reserved_regions_info(phys_addr_t *addr); |
| @@ -59,6 +68,28 @@ int memblock_remove(phys_addr_t base, phys_addr_t size); | |||
| 59 | int memblock_free(phys_addr_t base, phys_addr_t size); | 68 | int memblock_free(phys_addr_t base, phys_addr_t size); |
| 60 | int memblock_reserve(phys_addr_t base, phys_addr_t size); | 69 | int memblock_reserve(phys_addr_t base, phys_addr_t size); |
| 61 | void memblock_trim_memory(phys_addr_t align); | 70 | void memblock_trim_memory(phys_addr_t align); |
| 71 | int memblock_mark_hotplug(phys_addr_t base, phys_addr_t size); | ||
| 72 | int memblock_clear_hotplug(phys_addr_t base, phys_addr_t size); | ||
| 73 | #ifdef CONFIG_MOVABLE_NODE | ||
| 74 | static inline bool memblock_is_hotpluggable(struct memblock_region *m) | ||
| 75 | { | ||
| 76 | return m->flags & MEMBLOCK_HOTPLUG; | ||
| 77 | } | ||
| 78 | |||
| 79 | static inline bool movable_node_is_enabled(void) | ||
| 80 | { | ||
| 81 | return movable_node_enabled; | ||
| 82 | } | ||
| 83 | #else | ||
| 84 | static inline bool memblock_is_hotpluggable(struct memblock_region *m) | ||
| 85 | { | ||
| 86 | return false; | ||
| 87 | } | ||
| 88 | static inline bool movable_node_is_enabled(void) | ||
| 89 | { | ||
| 90 | return false; | ||
| 91 | } | ||
| 92 | #endif | ||
| 62 | 93 | ||
| 63 | #ifdef CONFIG_HAVE_MEMBLOCK_NODE_MAP | 94 | #ifdef CONFIG_HAVE_MEMBLOCK_NODE_MAP |
| 64 | int memblock_search_pfn_nid(unsigned long pfn, unsigned long *start_pfn, | 95 | int memblock_search_pfn_nid(unsigned long pfn, unsigned long *start_pfn, |
| @@ -87,7 +118,7 @@ void __next_free_mem_range(u64 *idx, int nid, phys_addr_t *out_start, | |||
| 87 | /** | 118 | /** |
| 88 | * for_each_free_mem_range - iterate through free memblock areas | 119 | * for_each_free_mem_range - iterate through free memblock areas |
| 89 | * @i: u64 used as loop variable | 120 | * @i: u64 used as loop variable |
| 90 | * @nid: node selector, %MAX_NUMNODES for all nodes | 121 | * @nid: node selector, %NUMA_NO_NODE for all nodes |
| 91 | * @p_start: ptr to phys_addr_t for start address of the range, can be %NULL | 122 | * @p_start: ptr to phys_addr_t for start address of the range, can be %NULL |
| 92 | * @p_end: ptr to phys_addr_t for end address of the range, can be %NULL | 123 | * @p_end: ptr to phys_addr_t for end address of the range, can be %NULL |
| 93 | * @p_nid: ptr to int for nid of the range, can be %NULL | 124 | * @p_nid: ptr to int for nid of the range, can be %NULL |
| @@ -107,7 +138,7 @@ void __next_free_mem_range_rev(u64 *idx, int nid, phys_addr_t *out_start, | |||
| 107 | /** | 138 | /** |
| 108 | * for_each_free_mem_range_reverse - rev-iterate through free memblock areas | 139 | * for_each_free_mem_range_reverse - rev-iterate through free memblock areas |
| 109 | * @i: u64 used as loop variable | 140 | * @i: u64 used as loop variable |
| 110 | * @nid: node selector, %MAX_NUMNODES for all nodes | 141 | * @nid: node selector, %NUMA_NO_NODE for all nodes |
| 111 | * @p_start: ptr to phys_addr_t for start address of the range, can be %NULL | 142 | * @p_start: ptr to phys_addr_t for start address of the range, can be %NULL |
| 112 | * @p_end: ptr to phys_addr_t for end address of the range, can be %NULL | 143 | * @p_end: ptr to phys_addr_t for end address of the range, can be %NULL |
| 113 | * @p_nid: ptr to int for nid of the range, can be %NULL | 144 | * @p_nid: ptr to int for nid of the range, can be %NULL |
| @@ -121,8 +152,21 @@ void __next_free_mem_range_rev(u64 *idx, int nid, phys_addr_t *out_start, | |||
| 121 | i != (u64)ULLONG_MAX; \ | 152 | i != (u64)ULLONG_MAX; \ |
| 122 | __next_free_mem_range_rev(&i, nid, p_start, p_end, p_nid)) | 153 | __next_free_mem_range_rev(&i, nid, p_start, p_end, p_nid)) |
| 123 | 154 | ||
| 155 | static inline void memblock_set_region_flags(struct memblock_region *r, | ||
| 156 | unsigned long flags) | ||
| 157 | { | ||
| 158 | r->flags |= flags; | ||
| 159 | } | ||
| 160 | |||
| 161 | static inline void memblock_clear_region_flags(struct memblock_region *r, | ||
| 162 | unsigned long flags) | ||
| 163 | { | ||
| 164 | r->flags &= ~flags; | ||
| 165 | } | ||
| 166 | |||
| 124 | #ifdef CONFIG_HAVE_MEMBLOCK_NODE_MAP | 167 | #ifdef CONFIG_HAVE_MEMBLOCK_NODE_MAP |
| 125 | int memblock_set_node(phys_addr_t base, phys_addr_t size, int nid); | 168 | int memblock_set_node(phys_addr_t base, phys_addr_t size, |
| 169 | struct memblock_type *type, int nid); | ||
| 126 | 170 | ||
| 127 | static inline void memblock_set_region_node(struct memblock_region *r, int nid) | 171 | static inline void memblock_set_region_node(struct memblock_region *r, int nid) |
| 128 | { | 172 | { |
diff --git a/include/linux/mempolicy.h b/include/linux/mempolicy.h index 9fe426b30a41..5f1ea756aace 100644 --- a/include/linux/mempolicy.h +++ b/include/linux/mempolicy.h | |||
| @@ -211,20 +211,8 @@ static inline void mpol_get(struct mempolicy *pol) | |||
| 211 | { | 211 | { |
| 212 | } | 212 | } |
| 213 | 213 | ||
| 214 | static inline struct mempolicy *mpol_dup(struct mempolicy *old) | ||
| 215 | { | ||
| 216 | return NULL; | ||
| 217 | } | ||
| 218 | |||
| 219 | struct shared_policy {}; | 214 | struct shared_policy {}; |
| 220 | 215 | ||
| 221 | static inline int mpol_set_shared_policy(struct shared_policy *info, | ||
| 222 | struct vm_area_struct *vma, | ||
| 223 | struct mempolicy *new) | ||
| 224 | { | ||
| 225 | return -EINVAL; | ||
| 226 | } | ||
| 227 | |||
| 228 | static inline void mpol_shared_policy_init(struct shared_policy *sp, | 216 | static inline void mpol_shared_policy_init(struct shared_policy *sp, |
| 229 | struct mempolicy *mpol) | 217 | struct mempolicy *mpol) |
| 230 | { | 218 | { |
| @@ -234,12 +222,6 @@ static inline void mpol_free_shared_policy(struct shared_policy *p) | |||
| 234 | { | 222 | { |
| 235 | } | 223 | } |
| 236 | 224 | ||
| 237 | static inline struct mempolicy * | ||
| 238 | mpol_shared_policy_lookup(struct shared_policy *sp, unsigned long idx) | ||
| 239 | { | ||
| 240 | return NULL; | ||
| 241 | } | ||
| 242 | |||
| 243 | #define vma_policy(vma) NULL | 225 | #define vma_policy(vma) NULL |
| 244 | 226 | ||
| 245 | static inline int | 227 | static inline int |
| @@ -266,10 +248,6 @@ static inline void mpol_rebind_mm(struct mm_struct *mm, nodemask_t *new) | |||
| 266 | { | 248 | { |
| 267 | } | 249 | } |
| 268 | 250 | ||
| 269 | static inline void mpol_fix_fork_child_flag(struct task_struct *p) | ||
| 270 | { | ||
| 271 | } | ||
| 272 | |||
| 273 | static inline struct zonelist *huge_zonelist(struct vm_area_struct *vma, | 251 | static inline struct zonelist *huge_zonelist(struct vm_area_struct *vma, |
| 274 | unsigned long addr, gfp_t gfp_flags, | 252 | unsigned long addr, gfp_t gfp_flags, |
| 275 | struct mempolicy **mpol, nodemask_t **nodemask) | 253 | struct mempolicy **mpol, nodemask_t **nodemask) |
| @@ -284,12 +262,6 @@ static inline bool init_nodemask_of_mempolicy(nodemask_t *m) | |||
| 284 | return false; | 262 | return false; |
| 285 | } | 263 | } |
| 286 | 264 | ||
| 287 | static inline bool mempolicy_nodemask_intersects(struct task_struct *tsk, | ||
| 288 | const nodemask_t *mask) | ||
| 289 | { | ||
| 290 | return false; | ||
| 291 | } | ||
| 292 | |||
| 293 | static inline int do_migrate_pages(struct mm_struct *mm, const nodemask_t *from, | 265 | static inline int do_migrate_pages(struct mm_struct *mm, const nodemask_t *from, |
| 294 | const nodemask_t *to, int flags) | 266 | const nodemask_t *to, int flags) |
| 295 | { | 267 | { |
| @@ -307,10 +279,6 @@ static inline int mpol_parse_str(char *str, struct mempolicy **mpol) | |||
| 307 | } | 279 | } |
| 308 | #endif | 280 | #endif |
| 309 | 281 | ||
| 310 | static inline void mpol_to_str(char *buffer, int maxlen, struct mempolicy *pol) | ||
| 311 | { | ||
| 312 | } | ||
| 313 | |||
| 314 | static inline int mpol_misplaced(struct page *page, struct vm_area_struct *vma, | 282 | static inline int mpol_misplaced(struct page *page, struct vm_area_struct *vma, |
| 315 | unsigned long address) | 283 | unsigned long address) |
| 316 | { | 284 | { |
diff --git a/include/linux/migrate.h b/include/linux/migrate.h index f015c059e159..84a31ad0b791 100644 --- a/include/linux/migrate.h +++ b/include/linux/migrate.h | |||
| @@ -35,16 +35,12 @@ enum migrate_reason { | |||
| 35 | 35 | ||
| 36 | #ifdef CONFIG_MIGRATION | 36 | #ifdef CONFIG_MIGRATION |
| 37 | 37 | ||
| 38 | extern void putback_lru_pages(struct list_head *l); | ||
| 39 | extern void putback_movable_pages(struct list_head *l); | 38 | extern void putback_movable_pages(struct list_head *l); |
| 40 | extern int migrate_page(struct address_space *, | 39 | extern int migrate_page(struct address_space *, |
| 41 | struct page *, struct page *, enum migrate_mode); | 40 | struct page *, struct page *, enum migrate_mode); |
| 42 | extern int migrate_pages(struct list_head *l, new_page_t x, | 41 | extern int migrate_pages(struct list_head *l, new_page_t x, |
| 43 | unsigned long private, enum migrate_mode mode, int reason); | 42 | unsigned long private, enum migrate_mode mode, int reason); |
| 44 | 43 | ||
| 45 | extern int fail_migrate_page(struct address_space *, | ||
| 46 | struct page *, struct page *); | ||
| 47 | |||
| 48 | extern int migrate_prep(void); | 44 | extern int migrate_prep(void); |
| 49 | extern int migrate_prep_local(void); | 45 | extern int migrate_prep_local(void); |
| 50 | extern int migrate_vmas(struct mm_struct *mm, | 46 | extern int migrate_vmas(struct mm_struct *mm, |
| @@ -59,7 +55,6 @@ extern int migrate_page_move_mapping(struct address_space *mapping, | |||
| 59 | int extra_count); | 55 | int extra_count); |
| 60 | #else | 56 | #else |
| 61 | 57 | ||
| 62 | static inline void putback_lru_pages(struct list_head *l) {} | ||
| 63 | static inline void putback_movable_pages(struct list_head *l) {} | 58 | static inline void putback_movable_pages(struct list_head *l) {} |
| 64 | static inline int migrate_pages(struct list_head *l, new_page_t x, | 59 | static inline int migrate_pages(struct list_head *l, new_page_t x, |
| 65 | unsigned long private, enum migrate_mode mode, int reason) | 60 | unsigned long private, enum migrate_mode mode, int reason) |
| @@ -86,7 +81,6 @@ static inline int migrate_huge_page_move_mapping(struct address_space *mapping, | |||
| 86 | 81 | ||
| 87 | /* Possible settings for the migrate_page() method in address_operations */ | 82 | /* Possible settings for the migrate_page() method in address_operations */ |
| 88 | #define migrate_page NULL | 83 | #define migrate_page NULL |
| 89 | #define fail_migrate_page NULL | ||
| 90 | 84 | ||
| 91 | #endif /* CONFIG_MIGRATION */ | 85 | #endif /* CONFIG_MIGRATION */ |
| 92 | 86 | ||
diff --git a/include/linux/mm.h b/include/linux/mm.h index 35527173cf50..a512dd836931 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h | |||
| @@ -57,6 +57,15 @@ extern int sysctl_legacy_va_layout; | |||
| 57 | extern unsigned long sysctl_user_reserve_kbytes; | 57 | extern unsigned long sysctl_user_reserve_kbytes; |
| 58 | extern unsigned long sysctl_admin_reserve_kbytes; | 58 | extern unsigned long sysctl_admin_reserve_kbytes; |
| 59 | 59 | ||
| 60 | extern int sysctl_overcommit_memory; | ||
| 61 | extern int sysctl_overcommit_ratio; | ||
| 62 | extern unsigned long sysctl_overcommit_kbytes; | ||
| 63 | |||
| 64 | extern int overcommit_ratio_handler(struct ctl_table *, int, void __user *, | ||
| 65 | size_t *, loff_t *); | ||
| 66 | extern int overcommit_kbytes_handler(struct ctl_table *, int, void __user *, | ||
| 67 | size_t *, loff_t *); | ||
| 68 | |||
| 60 | #define nth_page(page,n) pfn_to_page(page_to_pfn((page)) + (n)) | 69 | #define nth_page(page,n) pfn_to_page(page_to_pfn((page)) + (n)) |
| 61 | 70 | ||
| 62 | /* to align the pointer to the (next) page boundary */ | 71 | /* to align the pointer to the (next) page boundary */ |
| @@ -414,15 +423,44 @@ static inline int page_count(struct page *page) | |||
| 414 | return atomic_read(&compound_head(page)->_count); | 423 | return atomic_read(&compound_head(page)->_count); |
| 415 | } | 424 | } |
| 416 | 425 | ||
| 426 | #ifdef CONFIG_HUGETLB_PAGE | ||
| 427 | extern int PageHeadHuge(struct page *page_head); | ||
| 428 | #else /* CONFIG_HUGETLB_PAGE */ | ||
| 429 | static inline int PageHeadHuge(struct page *page_head) | ||
| 430 | { | ||
| 431 | return 0; | ||
| 432 | } | ||
| 433 | #endif /* CONFIG_HUGETLB_PAGE */ | ||
| 434 | |||
| 435 | static inline bool __compound_tail_refcounted(struct page *page) | ||
| 436 | { | ||
| 437 | return !PageSlab(page) && !PageHeadHuge(page); | ||
| 438 | } | ||
| 439 | |||
| 440 | /* | ||
| 441 | * This takes a head page as parameter and tells if the | ||
| 442 | * tail page reference counting can be skipped. | ||
| 443 | * | ||
| 444 | * For this to be safe, PageSlab and PageHeadHuge must remain true on | ||
| 445 | * any given page where they return true here, until all tail pins | ||
| 446 | * have been released. | ||
| 447 | */ | ||
| 448 | static inline bool compound_tail_refcounted(struct page *page) | ||
| 449 | { | ||
| 450 | VM_BUG_ON(!PageHead(page)); | ||
| 451 | return __compound_tail_refcounted(page); | ||
| 452 | } | ||
| 453 | |||
| 417 | static inline void get_huge_page_tail(struct page *page) | 454 | static inline void get_huge_page_tail(struct page *page) |
| 418 | { | 455 | { |
| 419 | /* | 456 | /* |
| 420 | * __split_huge_page_refcount() cannot run | 457 | * __split_huge_page_refcount() cannot run from under us. |
| 421 | * from under us. | ||
| 422 | */ | 458 | */ |
| 459 | VM_BUG_ON(!PageTail(page)); | ||
| 423 | VM_BUG_ON(page_mapcount(page) < 0); | 460 | VM_BUG_ON(page_mapcount(page) < 0); |
| 424 | VM_BUG_ON(atomic_read(&page->_count) != 0); | 461 | VM_BUG_ON(atomic_read(&page->_count) != 0); |
| 425 | atomic_inc(&page->_mapcount); | 462 | if (compound_tail_refcounted(page->first_page)) |
| 463 | atomic_inc(&page->_mapcount); | ||
| 426 | } | 464 | } |
| 427 | 465 | ||
| 428 | extern bool __get_page_tail(struct page *page); | 466 | extern bool __get_page_tail(struct page *page); |
| @@ -846,11 +884,14 @@ static __always_inline void *lowmem_page_address(const struct page *page) | |||
| 846 | #endif | 884 | #endif |
| 847 | 885 | ||
| 848 | #if defined(WANT_PAGE_VIRTUAL) | 886 | #if defined(WANT_PAGE_VIRTUAL) |
| 849 | #define page_address(page) ((page)->virtual) | 887 | static inline void *page_address(const struct page *page) |
| 850 | #define set_page_address(page, address) \ | 888 | { |
| 851 | do { \ | 889 | return page->virtual; |
| 852 | (page)->virtual = (address); \ | 890 | } |
| 853 | } while(0) | 891 | static inline void set_page_address(struct page *page, void *address) |
| 892 | { | ||
| 893 | page->virtual = address; | ||
| 894 | } | ||
| 854 | #define page_address_init() do { } while(0) | 895 | #define page_address_init() do { } while(0) |
| 855 | #endif | 896 | #endif |
| 856 | 897 | ||
| @@ -984,7 +1025,6 @@ extern void pagefault_out_of_memory(void); | |||
| 984 | * various contexts. | 1025 | * various contexts. |
| 985 | */ | 1026 | */ |
| 986 | #define SHOW_MEM_FILTER_NODES (0x0001u) /* disallowed nodes */ | 1027 | #define SHOW_MEM_FILTER_NODES (0x0001u) /* disallowed nodes */ |
| 987 | #define SHOW_MEM_FILTER_PAGE_COUNT (0x0002u) /* page type count */ | ||
| 988 | 1028 | ||
| 989 | extern void show_free_areas(unsigned int flags); | 1029 | extern void show_free_areas(unsigned int flags); |
| 990 | extern bool skip_free_areas_node(unsigned int flags, int nid); | 1030 | extern bool skip_free_areas_node(unsigned int flags, int nid); |
| @@ -1318,6 +1358,7 @@ static inline pmd_t *pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long a | |||
| 1318 | 1358 | ||
| 1319 | #if USE_SPLIT_PTE_PTLOCKS | 1359 | #if USE_SPLIT_PTE_PTLOCKS |
| 1320 | #if ALLOC_SPLIT_PTLOCKS | 1360 | #if ALLOC_SPLIT_PTLOCKS |
| 1361 | void __init ptlock_cache_init(void); | ||
| 1321 | extern bool ptlock_alloc(struct page *page); | 1362 | extern bool ptlock_alloc(struct page *page); |
| 1322 | extern void ptlock_free(struct page *page); | 1363 | extern void ptlock_free(struct page *page); |
| 1323 | 1364 | ||
| @@ -1326,6 +1367,10 @@ static inline spinlock_t *ptlock_ptr(struct page *page) | |||
| 1326 | return page->ptl; | 1367 | return page->ptl; |
| 1327 | } | 1368 | } |
| 1328 | #else /* ALLOC_SPLIT_PTLOCKS */ | 1369 | #else /* ALLOC_SPLIT_PTLOCKS */ |
| 1370 | static inline void ptlock_cache_init(void) | ||
| 1371 | { | ||
| 1372 | } | ||
| 1373 | |||
| 1329 | static inline bool ptlock_alloc(struct page *page) | 1374 | static inline bool ptlock_alloc(struct page *page) |
| 1330 | { | 1375 | { |
| 1331 | return true; | 1376 | return true; |
| @@ -1378,10 +1423,17 @@ static inline spinlock_t *pte_lockptr(struct mm_struct *mm, pmd_t *pmd) | |||
| 1378 | { | 1423 | { |
| 1379 | return &mm->page_table_lock; | 1424 | return &mm->page_table_lock; |
| 1380 | } | 1425 | } |
| 1426 | static inline void ptlock_cache_init(void) {} | ||
| 1381 | static inline bool ptlock_init(struct page *page) { return true; } | 1427 | static inline bool ptlock_init(struct page *page) { return true; } |
| 1382 | static inline void pte_lock_deinit(struct page *page) {} | 1428 | static inline void pte_lock_deinit(struct page *page) {} |
| 1383 | #endif /* USE_SPLIT_PTE_PTLOCKS */ | 1429 | #endif /* USE_SPLIT_PTE_PTLOCKS */ |
| 1384 | 1430 | ||
| 1431 | static inline void pgtable_init(void) | ||
| 1432 | { | ||
| 1433 | ptlock_cache_init(); | ||
| 1434 | pgtable_cache_init(); | ||
| 1435 | } | ||
| 1436 | |||
| 1385 | static inline bool pgtable_page_ctor(struct page *page) | 1437 | static inline bool pgtable_page_ctor(struct page *page) |
| 1386 | { | 1438 | { |
| 1387 | inc_zone_page_state(page, NR_PAGETABLE); | 1439 | inc_zone_page_state(page, NR_PAGETABLE); |
diff --git a/include/linux/mman.h b/include/linux/mman.h index 7f7f8dae4b1d..16373c8f5f57 100644 --- a/include/linux/mman.h +++ b/include/linux/mman.h | |||
| @@ -9,6 +9,7 @@ | |||
| 9 | 9 | ||
| 10 | extern int sysctl_overcommit_memory; | 10 | extern int sysctl_overcommit_memory; |
| 11 | extern int sysctl_overcommit_ratio; | 11 | extern int sysctl_overcommit_ratio; |
| 12 | extern unsigned long sysctl_overcommit_kbytes; | ||
| 12 | extern struct percpu_counter vm_committed_as; | 13 | extern struct percpu_counter vm_committed_as; |
| 13 | 14 | ||
| 14 | #ifdef CONFIG_SMP | 15 | #ifdef CONFIG_SMP |
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index bd791e452ad7..5f2052c83154 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h | |||
| @@ -490,6 +490,12 @@ struct zone { | |||
| 490 | unsigned long managed_pages; | 490 | unsigned long managed_pages; |
| 491 | 491 | ||
| 492 | /* | 492 | /* |
| 493 | * Number of MIGRATE_RESEVE page block. To maintain for just | ||
| 494 | * optimization. Protected by zone->lock. | ||
| 495 | */ | ||
| 496 | int nr_migrate_reserve_block; | ||
| 497 | |||
| 498 | /* | ||
| 493 | * rarely used fields: | 499 | * rarely used fields: |
| 494 | */ | 500 | */ |
| 495 | const char *name; | 501 | const char *name; |
| @@ -758,10 +764,7 @@ typedef struct pglist_data { | |||
| 758 | int kswapd_max_order; | 764 | int kswapd_max_order; |
| 759 | enum zone_type classzone_idx; | 765 | enum zone_type classzone_idx; |
| 760 | #ifdef CONFIG_NUMA_BALANCING | 766 | #ifdef CONFIG_NUMA_BALANCING |
| 761 | /* | 767 | /* Lock serializing the migrate rate limiting window */ |
| 762 | * Lock serializing the per destination node AutoNUMA memory | ||
| 763 | * migration rate limiting data. | ||
| 764 | */ | ||
| 765 | spinlock_t numabalancing_migrate_lock; | 768 | spinlock_t numabalancing_migrate_lock; |
| 766 | 769 | ||
| 767 | /* Rate limiting time interval */ | 770 | /* Rate limiting time interval */ |
diff --git a/include/linux/posix_acl.h b/include/linux/posix_acl.h index 7931efe71175..fb616942e4c7 100644 --- a/include/linux/posix_acl.h +++ b/include/linux/posix_acl.h | |||
| @@ -94,78 +94,12 @@ extern int posix_acl_chmod(struct posix_acl **, gfp_t, umode_t); | |||
| 94 | extern struct posix_acl *get_posix_acl(struct inode *, int); | 94 | extern struct posix_acl *get_posix_acl(struct inode *, int); |
| 95 | extern int set_posix_acl(struct inode *, int, struct posix_acl *); | 95 | extern int set_posix_acl(struct inode *, int, struct posix_acl *); |
| 96 | 96 | ||
| 97 | #ifdef CONFIG_FS_POSIX_ACL | 97 | struct posix_acl **acl_by_type(struct inode *inode, int type); |
| 98 | static inline struct posix_acl **acl_by_type(struct inode *inode, int type) | 98 | struct posix_acl *get_cached_acl(struct inode *inode, int type); |
| 99 | { | 99 | struct posix_acl *get_cached_acl_rcu(struct inode *inode, int type); |
| 100 | switch (type) { | 100 | void set_cached_acl(struct inode *inode, int type, struct posix_acl *acl); |
| 101 | case ACL_TYPE_ACCESS: | 101 | void forget_cached_acl(struct inode *inode, int type); |
| 102 | return &inode->i_acl; | 102 | void forget_all_cached_acls(struct inode *inode); |
| 103 | case ACL_TYPE_DEFAULT: | ||
| 104 | return &inode->i_default_acl; | ||
| 105 | default: | ||
| 106 | BUG(); | ||
| 107 | } | ||
| 108 | } | ||
| 109 | |||
| 110 | static inline struct posix_acl *get_cached_acl(struct inode *inode, int type) | ||
| 111 | { | ||
| 112 | struct posix_acl **p = acl_by_type(inode, type); | ||
| 113 | struct posix_acl *acl = ACCESS_ONCE(*p); | ||
| 114 | if (acl) { | ||
| 115 | spin_lock(&inode->i_lock); | ||
| 116 | acl = *p; | ||
| 117 | if (acl != ACL_NOT_CACHED) | ||
| 118 | acl = posix_acl_dup(acl); | ||
| 119 | spin_unlock(&inode->i_lock); | ||
| 120 | } | ||
| 121 | return acl; | ||
| 122 | } | ||
| 123 | |||
| 124 | static inline struct posix_acl *get_cached_acl_rcu(struct inode *inode, int type) | ||
| 125 | { | ||
| 126 | return rcu_dereference(*acl_by_type(inode, type)); | ||
| 127 | } | ||
| 128 | |||
| 129 | static inline void set_cached_acl(struct inode *inode, | ||
| 130 | int type, | ||
| 131 | struct posix_acl *acl) | ||
| 132 | { | ||
| 133 | struct posix_acl **p = acl_by_type(inode, type); | ||
| 134 | struct posix_acl *old; | ||
| 135 | spin_lock(&inode->i_lock); | ||
| 136 | old = *p; | ||
| 137 | rcu_assign_pointer(*p, posix_acl_dup(acl)); | ||
| 138 | spin_unlock(&inode->i_lock); | ||
| 139 | if (old != ACL_NOT_CACHED) | ||
| 140 | posix_acl_release(old); | ||
| 141 | } | ||
| 142 | |||
| 143 | static inline void forget_cached_acl(struct inode *inode, int type) | ||
| 144 | { | ||
| 145 | struct posix_acl **p = acl_by_type(inode, type); | ||
| 146 | struct posix_acl *old; | ||
| 147 | spin_lock(&inode->i_lock); | ||
| 148 | old = *p; | ||
| 149 | *p = ACL_NOT_CACHED; | ||
| 150 | spin_unlock(&inode->i_lock); | ||
| 151 | if (old != ACL_NOT_CACHED) | ||
| 152 | posix_acl_release(old); | ||
| 153 | } | ||
| 154 | |||
| 155 | static inline void forget_all_cached_acls(struct inode *inode) | ||
| 156 | { | ||
| 157 | struct posix_acl *old_access, *old_default; | ||
| 158 | spin_lock(&inode->i_lock); | ||
| 159 | old_access = inode->i_acl; | ||
| 160 | old_default = inode->i_default_acl; | ||
| 161 | inode->i_acl = inode->i_default_acl = ACL_NOT_CACHED; | ||
| 162 | spin_unlock(&inode->i_lock); | ||
| 163 | if (old_access != ACL_NOT_CACHED) | ||
| 164 | posix_acl_release(old_access); | ||
| 165 | if (old_default != ACL_NOT_CACHED) | ||
| 166 | posix_acl_release(old_default); | ||
| 167 | } | ||
| 168 | #endif | ||
| 169 | 103 | ||
| 170 | static inline void cache_no_acl(struct inode *inode) | 104 | static inline void cache_no_acl(struct inode *inode) |
| 171 | { | 105 | { |
diff --git a/include/linux/rmap.h b/include/linux/rmap.h index 6dacb93a6d94..1da693d51255 100644 --- a/include/linux/rmap.h +++ b/include/linux/rmap.h | |||
| @@ -184,13 +184,13 @@ static inline void page_dup_rmap(struct page *page) | |||
| 184 | int page_referenced(struct page *, int is_locked, | 184 | int page_referenced(struct page *, int is_locked, |
| 185 | struct mem_cgroup *memcg, unsigned long *vm_flags); | 185 | struct mem_cgroup *memcg, unsigned long *vm_flags); |
| 186 | int page_referenced_one(struct page *, struct vm_area_struct *, | 186 | int page_referenced_one(struct page *, struct vm_area_struct *, |
| 187 | unsigned long address, unsigned int *mapcount, unsigned long *vm_flags); | 187 | unsigned long address, void *arg); |
| 188 | 188 | ||
| 189 | #define TTU_ACTION(x) ((x) & TTU_ACTION_MASK) | 189 | #define TTU_ACTION(x) ((x) & TTU_ACTION_MASK) |
| 190 | 190 | ||
| 191 | int try_to_unmap(struct page *, enum ttu_flags flags); | 191 | int try_to_unmap(struct page *, enum ttu_flags flags); |
| 192 | int try_to_unmap_one(struct page *, struct vm_area_struct *, | 192 | int try_to_unmap_one(struct page *, struct vm_area_struct *, |
| 193 | unsigned long address, enum ttu_flags flags); | 193 | unsigned long address, void *arg); |
| 194 | 194 | ||
| 195 | /* | 195 | /* |
| 196 | * Called from mm/filemap_xip.c to unmap empty zero page | 196 | * Called from mm/filemap_xip.c to unmap empty zero page |
| @@ -236,10 +236,27 @@ void page_unlock_anon_vma_read(struct anon_vma *anon_vma); | |||
| 236 | int page_mapped_in_vma(struct page *page, struct vm_area_struct *vma); | 236 | int page_mapped_in_vma(struct page *page, struct vm_area_struct *vma); |
| 237 | 237 | ||
| 238 | /* | 238 | /* |
| 239 | * Called by migrate.c to remove migration ptes, but might be used more later. | 239 | * rmap_walk_control: To control rmap traversing for specific needs |
| 240 | * | ||
| 241 | * arg: passed to rmap_one() and invalid_vma() | ||
| 242 | * rmap_one: executed on each vma where page is mapped | ||
| 243 | * done: for checking traversing termination condition | ||
| 244 | * file_nonlinear: for handling file nonlinear mapping | ||
| 245 | * anon_lock: for getting anon_lock by optimized way rather than default | ||
| 246 | * invalid_vma: for skipping uninterested vma | ||
| 240 | */ | 247 | */ |
| 241 | int rmap_walk(struct page *page, int (*rmap_one)(struct page *, | 248 | struct rmap_walk_control { |
| 242 | struct vm_area_struct *, unsigned long, void *), void *arg); | 249 | void *arg; |
| 250 | int (*rmap_one)(struct page *page, struct vm_area_struct *vma, | ||
| 251 | unsigned long addr, void *arg); | ||
| 252 | int (*done)(struct page *page); | ||
| 253 | int (*file_nonlinear)(struct page *, struct address_space *, | ||
| 254 | struct vm_area_struct *vma); | ||
| 255 | struct anon_vma *(*anon_lock)(struct page *page); | ||
| 256 | bool (*invalid_vma)(struct vm_area_struct *vma, void *arg); | ||
| 257 | }; | ||
| 258 | |||
| 259 | int rmap_walk(struct page *page, struct rmap_walk_control *rwc); | ||
| 243 | 260 | ||
| 244 | #else /* !CONFIG_MMU */ | 261 | #else /* !CONFIG_MMU */ |
| 245 | 262 | ||
diff --git a/include/linux/sched.h b/include/linux/sched.h index ffccdad050b5..485234d2fd42 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
| @@ -549,6 +549,7 @@ struct signal_struct { | |||
| 549 | atomic_t sigcnt; | 549 | atomic_t sigcnt; |
| 550 | atomic_t live; | 550 | atomic_t live; |
| 551 | int nr_threads; | 551 | int nr_threads; |
| 552 | struct list_head thread_head; | ||
| 552 | 553 | ||
| 553 | wait_queue_head_t wait_chldexit; /* for wait4() */ | 554 | wait_queue_head_t wait_chldexit; /* for wait4() */ |
| 554 | 555 | ||
| @@ -1271,6 +1272,7 @@ struct task_struct { | |||
| 1271 | /* PID/PID hash table linkage. */ | 1272 | /* PID/PID hash table linkage. */ |
| 1272 | struct pid_link pids[PIDTYPE_MAX]; | 1273 | struct pid_link pids[PIDTYPE_MAX]; |
| 1273 | struct list_head thread_group; | 1274 | struct list_head thread_group; |
| 1275 | struct list_head thread_node; | ||
| 1274 | 1276 | ||
| 1275 | struct completion *vfork_done; /* for vfork() */ | 1277 | struct completion *vfork_done; /* for vfork() */ |
| 1276 | int __user *set_child_tid; /* CLONE_CHILD_SETTID */ | 1278 | int __user *set_child_tid; /* CLONE_CHILD_SETTID */ |
| @@ -2341,6 +2343,16 @@ extern bool current_is_single_threaded(void); | |||
| 2341 | #define while_each_thread(g, t) \ | 2343 | #define while_each_thread(g, t) \ |
| 2342 | while ((t = next_thread(t)) != g) | 2344 | while ((t = next_thread(t)) != g) |
| 2343 | 2345 | ||
| 2346 | #define __for_each_thread(signal, t) \ | ||
| 2347 | list_for_each_entry_rcu(t, &(signal)->thread_head, thread_node) | ||
| 2348 | |||
| 2349 | #define for_each_thread(p, t) \ | ||
| 2350 | __for_each_thread((p)->signal, t) | ||
| 2351 | |||
| 2352 | /* Careful: this is a double loop, 'break' won't work as expected. */ | ||
| 2353 | #define for_each_process_thread(p, t) \ | ||
| 2354 | for_each_process(p) for_each_thread(p, t) | ||
| 2355 | |||
| 2344 | static inline int get_nr_threads(struct task_struct *tsk) | 2356 | static inline int get_nr_threads(struct task_struct *tsk) |
| 2345 | { | 2357 | { |
| 2346 | return tsk->signal->nr_threads; | 2358 | return tsk->signal->nr_threads; |
