diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-09-17 18:01:14 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-09-17 18:01:14 -0400 |
commit | 08077ca849ced0306ce842ed597b0d80434a8bf0 (patch) | |
tree | a1c7b602fc2f945dc65493a06042a7dc0d09d85a | |
parent | 2ade0b7f795293ca0b11c1bf3d2f99ed33e04a2a (diff) | |
parent | f14851af0ebb32745c6c5a2e400aa0549f9d20df (diff) |
Merge branch 'akpm' (Andrew's patch-bomb)
Merge fixes from Andrew Morton:
"13 patches. 12 are fixes and one is a little preparatory thing for
Andi."
* emailed patches from Andrew Morton <akpm@linux-foundation.org>: (13 commits)
memory hotplug: fix section info double registration bug
mm/page_alloc: fix the page address of higher page's buddy calculation
drivers/rtc/rtc-twl.c: ensure all interrupts are disabled during probe
compiler.h: add __visible
pid-namespace: limit value of ns_last_pid to (0, max_pid)
include/net/sock.h: squelch compiler warning in sk_rmem_schedule()
slub: consider pfmemalloc_match() in get_partial_node()
slab: fix starting index for finding another object
slab: do ClearSlabPfmemalloc() for all pages of slab
nbd: clear waiting_queue on shutdown
MAINTAINERS: fix TXT maintainer list and source repo path
mm/ia64: fix a memory block size bug
memory hotplug: reset pgdat->kswapd to NULL if creating kernel thread fails
-rw-r--r-- | MAINTAINERS | 5 | ||||
-rw-r--r-- | drivers/block/nbd.c | 9 | ||||
-rw-r--r-- | drivers/rtc/rtc-twl.c | 5 | ||||
-rw-r--r-- | include/linux/compiler-gcc4.h | 7 | ||||
-rw-r--r-- | include/linux/compiler.h | 4 | ||||
-rw-r--r-- | include/linux/memory.h | 2 | ||||
-rw-r--r-- | include/net/sock.h | 2 | ||||
-rw-r--r-- | kernel/pid_namespace.c | 6 | ||||
-rw-r--r-- | mm/memory_hotplug.c | 16 | ||||
-rw-r--r-- | mm/page_alloc.c | 2 | ||||
-rw-r--r-- | mm/slab.c | 6 | ||||
-rw-r--r-- | mm/slub.c | 15 | ||||
-rw-r--r-- | mm/vmscan.c | 1 |
13 files changed, 60 insertions, 20 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 53cc13c82cb1..b17587d9412f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -3666,11 +3666,12 @@ F: Documentation/networking/README.ipw2200 | |||
3666 | F: drivers/net/wireless/ipw2x00/ | 3666 | F: drivers/net/wireless/ipw2x00/ |
3667 | 3667 | ||
3668 | INTEL(R) TRUSTED EXECUTION TECHNOLOGY (TXT) | 3668 | INTEL(R) TRUSTED EXECUTION TECHNOLOGY (TXT) |
3669 | M: Joseph Cihula <joseph.cihula@intel.com> | 3669 | M: Richard L Maliszewski <richard.l.maliszewski@intel.com> |
3670 | M: Gang Wei <gang.wei@intel.com> | ||
3670 | M: Shane Wang <shane.wang@intel.com> | 3671 | M: Shane Wang <shane.wang@intel.com> |
3671 | L: tboot-devel@lists.sourceforge.net | 3672 | L: tboot-devel@lists.sourceforge.net |
3672 | W: http://tboot.sourceforge.net | 3673 | W: http://tboot.sourceforge.net |
3673 | T: Mercurial http://www.bughost.org/repos.hg/tboot.hg | 3674 | T: hg http://tboot.hg.sourceforge.net:8000/hgroot/tboot/tboot |
3674 | S: Supported | 3675 | S: Supported |
3675 | F: Documentation/intel_txt.txt | 3676 | F: Documentation/intel_txt.txt |
3676 | F: include/linux/tboot.h | 3677 | F: include/linux/tboot.h |
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index d07c9f7fded6..0c03411c59eb 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c | |||
@@ -449,6 +449,14 @@ static void nbd_clear_que(struct nbd_device *nbd) | |||
449 | req->errors++; | 449 | req->errors++; |
450 | nbd_end_request(req); | 450 | nbd_end_request(req); |
451 | } | 451 | } |
452 | |||
453 | while (!list_empty(&nbd->waiting_queue)) { | ||
454 | req = list_entry(nbd->waiting_queue.next, struct request, | ||
455 | queuelist); | ||
456 | list_del_init(&req->queuelist); | ||
457 | req->errors++; | ||
458 | nbd_end_request(req); | ||
459 | } | ||
452 | } | 460 | } |
453 | 461 | ||
454 | 462 | ||
@@ -598,6 +606,7 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd, | |||
598 | nbd->file = NULL; | 606 | nbd->file = NULL; |
599 | nbd_clear_que(nbd); | 607 | nbd_clear_que(nbd); |
600 | BUG_ON(!list_empty(&nbd->queue_head)); | 608 | BUG_ON(!list_empty(&nbd->queue_head)); |
609 | BUG_ON(!list_empty(&nbd->waiting_queue)); | ||
601 | if (file) | 610 | if (file) |
602 | fput(file); | 611 | fput(file); |
603 | return 0; | 612 | return 0; |
diff --git a/drivers/rtc/rtc-twl.c b/drivers/rtc/rtc-twl.c index c5d06fe83bba..9277d945bf48 100644 --- a/drivers/rtc/rtc-twl.c +++ b/drivers/rtc/rtc-twl.c | |||
@@ -495,6 +495,11 @@ static int __devinit twl_rtc_probe(struct platform_device *pdev) | |||
495 | if (ret < 0) | 495 | if (ret < 0) |
496 | goto out1; | 496 | goto out1; |
497 | 497 | ||
498 | /* ensure interrupts are disabled, bootloaders can be strange */ | ||
499 | ret = twl_rtc_write_u8(0, REG_RTC_INTERRUPTS_REG); | ||
500 | if (ret < 0) | ||
501 | dev_warn(&pdev->dev, "unable to disable interrupt\n"); | ||
502 | |||
498 | /* init cached IRQ enable bits */ | 503 | /* init cached IRQ enable bits */ |
499 | ret = twl_rtc_read_u8(&rtc_irq_bits, REG_RTC_INTERRUPTS_REG); | 504 | ret = twl_rtc_read_u8(&rtc_irq_bits, REG_RTC_INTERRUPTS_REG); |
500 | if (ret < 0) | 505 | if (ret < 0) |
diff --git a/include/linux/compiler-gcc4.h b/include/linux/compiler-gcc4.h index 2f4079175afb..934bc34d5f99 100644 --- a/include/linux/compiler-gcc4.h +++ b/include/linux/compiler-gcc4.h | |||
@@ -49,6 +49,13 @@ | |||
49 | #endif | 49 | #endif |
50 | #endif | 50 | #endif |
51 | 51 | ||
52 | #if __GNUC_MINOR__ >= 6 | ||
53 | /* | ||
54 | * Tell the optimizer that something else uses this function or variable. | ||
55 | */ | ||
56 | #define __visible __attribute__((externally_visible)) | ||
57 | #endif | ||
58 | |||
52 | #if __GNUC_MINOR__ > 0 | 59 | #if __GNUC_MINOR__ > 0 |
53 | #define __compiletime_object_size(obj) __builtin_object_size(obj, 0) | 60 | #define __compiletime_object_size(obj) __builtin_object_size(obj, 0) |
54 | #endif | 61 | #endif |
diff --git a/include/linux/compiler.h b/include/linux/compiler.h index 923d093c9cea..f430e4162f41 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h | |||
@@ -278,6 +278,10 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect); | |||
278 | # define __section(S) __attribute__ ((__section__(#S))) | 278 | # define __section(S) __attribute__ ((__section__(#S))) |
279 | #endif | 279 | #endif |
280 | 280 | ||
281 | #ifndef __visible | ||
282 | #define __visible | ||
283 | #endif | ||
284 | |||
281 | /* Are two types/vars the same type (ignoring qualifiers)? */ | 285 | /* Are two types/vars the same type (ignoring qualifiers)? */ |
282 | #ifndef __same_type | 286 | #ifndef __same_type |
283 | # define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b)) | 287 | # define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b)) |
diff --git a/include/linux/memory.h b/include/linux/memory.h index 1ac7f6e405f9..ff9a9f8e0ed9 100644 --- a/include/linux/memory.h +++ b/include/linux/memory.h | |||
@@ -19,7 +19,7 @@ | |||
19 | #include <linux/compiler.h> | 19 | #include <linux/compiler.h> |
20 | #include <linux/mutex.h> | 20 | #include <linux/mutex.h> |
21 | 21 | ||
22 | #define MIN_MEMORY_BLOCK_SIZE (1 << SECTION_SIZE_BITS) | 22 | #define MIN_MEMORY_BLOCK_SIZE (1UL << SECTION_SIZE_BITS) |
23 | 23 | ||
24 | struct memory_block { | 24 | struct memory_block { |
25 | unsigned long start_section_nr; | 25 | unsigned long start_section_nr; |
diff --git a/include/net/sock.h b/include/net/sock.h index 72132aef53fc..adb7da20b5a1 100644 --- a/include/net/sock.h +++ b/include/net/sock.h | |||
@@ -1332,7 +1332,7 @@ static inline bool sk_wmem_schedule(struct sock *sk, int size) | |||
1332 | } | 1332 | } |
1333 | 1333 | ||
1334 | static inline bool | 1334 | static inline bool |
1335 | sk_rmem_schedule(struct sock *sk, struct sk_buff *skb, unsigned int size) | 1335 | sk_rmem_schedule(struct sock *sk, struct sk_buff *skb, int size) |
1336 | { | 1336 | { |
1337 | if (!sk_has_account(sk)) | 1337 | if (!sk_has_account(sk)) |
1338 | return true; | 1338 | return true; |
diff --git a/kernel/pid_namespace.c b/kernel/pid_namespace.c index b3c7fd554250..6144bab8fd8e 100644 --- a/kernel/pid_namespace.c +++ b/kernel/pid_namespace.c | |||
@@ -232,15 +232,19 @@ static int pid_ns_ctl_handler(struct ctl_table *table, int write, | |||
232 | */ | 232 | */ |
233 | 233 | ||
234 | tmp.data = ¤t->nsproxy->pid_ns->last_pid; | 234 | tmp.data = ¤t->nsproxy->pid_ns->last_pid; |
235 | return proc_dointvec(&tmp, write, buffer, lenp, ppos); | 235 | return proc_dointvec_minmax(&tmp, write, buffer, lenp, ppos); |
236 | } | 236 | } |
237 | 237 | ||
238 | extern int pid_max; | ||
239 | static int zero = 0; | ||
238 | static struct ctl_table pid_ns_ctl_table[] = { | 240 | static struct ctl_table pid_ns_ctl_table[] = { |
239 | { | 241 | { |
240 | .procname = "ns_last_pid", | 242 | .procname = "ns_last_pid", |
241 | .maxlen = sizeof(int), | 243 | .maxlen = sizeof(int), |
242 | .mode = 0666, /* permissions are checked in the handler */ | 244 | .mode = 0666, /* permissions are checked in the handler */ |
243 | .proc_handler = pid_ns_ctl_handler, | 245 | .proc_handler = pid_ns_ctl_handler, |
246 | .extra1 = &zero, | ||
247 | .extra2 = &pid_max, | ||
244 | }, | 248 | }, |
245 | { } | 249 | { } |
246 | }; | 250 | }; |
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index 3ad25f9d1fc1..6a5b90d0cfd7 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c | |||
@@ -126,9 +126,6 @@ static void register_page_bootmem_info_section(unsigned long start_pfn) | |||
126 | struct mem_section *ms; | 126 | struct mem_section *ms; |
127 | struct page *page, *memmap; | 127 | struct page *page, *memmap; |
128 | 128 | ||
129 | if (!pfn_valid(start_pfn)) | ||
130 | return; | ||
131 | |||
132 | section_nr = pfn_to_section_nr(start_pfn); | 129 | section_nr = pfn_to_section_nr(start_pfn); |
133 | ms = __nr_to_section(section_nr); | 130 | ms = __nr_to_section(section_nr); |
134 | 131 | ||
@@ -187,9 +184,16 @@ void register_page_bootmem_info_node(struct pglist_data *pgdat) | |||
187 | end_pfn = pfn + pgdat->node_spanned_pages; | 184 | end_pfn = pfn + pgdat->node_spanned_pages; |
188 | 185 | ||
189 | /* register_section info */ | 186 | /* register_section info */ |
190 | for (; pfn < end_pfn; pfn += PAGES_PER_SECTION) | 187 | for (; pfn < end_pfn; pfn += PAGES_PER_SECTION) { |
191 | register_page_bootmem_info_section(pfn); | 188 | /* |
192 | 189 | * Some platforms can assign the same pfn to multiple nodes - on | |
190 | * node0 as well as nodeN. To avoid registering a pfn against | ||
191 | * multiple nodes we check that this pfn does not already | ||
192 | * reside in some other node. | ||
193 | */ | ||
194 | if (pfn_valid(pfn) && (pfn_to_nid(pfn) == node)) | ||
195 | register_page_bootmem_info_section(pfn); | ||
196 | } | ||
193 | } | 197 | } |
194 | #endif /* !CONFIG_SPARSEMEM_VMEMMAP */ | 198 | #endif /* !CONFIG_SPARSEMEM_VMEMMAP */ |
195 | 199 | ||
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index c66fb875104a..c13ea7538891 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -584,7 +584,7 @@ static inline void __free_one_page(struct page *page, | |||
584 | combined_idx = buddy_idx & page_idx; | 584 | combined_idx = buddy_idx & page_idx; |
585 | higher_page = page + (combined_idx - page_idx); | 585 | higher_page = page + (combined_idx - page_idx); |
586 | buddy_idx = __find_buddy_index(combined_idx, order + 1); | 586 | buddy_idx = __find_buddy_index(combined_idx, order + 1); |
587 | higher_buddy = page + (buddy_idx - combined_idx); | 587 | higher_buddy = higher_page + (buddy_idx - combined_idx); |
588 | if (page_is_buddy(higher_page, higher_buddy, order + 1)) { | 588 | if (page_is_buddy(higher_page, higher_buddy, order + 1)) { |
589 | list_add_tail(&page->lru, | 589 | list_add_tail(&page->lru, |
590 | &zone->free_area[order].free_list[migratetype]); | 590 | &zone->free_area[order].free_list[migratetype]); |
@@ -983,7 +983,7 @@ static void *__ac_get_obj(struct kmem_cache *cachep, struct array_cache *ac, | |||
983 | } | 983 | } |
984 | 984 | ||
985 | /* The caller cannot use PFMEMALLOC objects, find another one */ | 985 | /* The caller cannot use PFMEMALLOC objects, find another one */ |
986 | for (i = 1; i < ac->avail; i++) { | 986 | for (i = 0; i < ac->avail; i++) { |
987 | /* If a !PFMEMALLOC object is found, swap them */ | 987 | /* If a !PFMEMALLOC object is found, swap them */ |
988 | if (!is_obj_pfmemalloc(ac->entry[i])) { | 988 | if (!is_obj_pfmemalloc(ac->entry[i])) { |
989 | objp = ac->entry[i]; | 989 | objp = ac->entry[i]; |
@@ -1000,7 +1000,7 @@ static void *__ac_get_obj(struct kmem_cache *cachep, struct array_cache *ac, | |||
1000 | l3 = cachep->nodelists[numa_mem_id()]; | 1000 | l3 = cachep->nodelists[numa_mem_id()]; |
1001 | if (!list_empty(&l3->slabs_free) && force_refill) { | 1001 | if (!list_empty(&l3->slabs_free) && force_refill) { |
1002 | struct slab *slabp = virt_to_slab(objp); | 1002 | struct slab *slabp = virt_to_slab(objp); |
1003 | ClearPageSlabPfmemalloc(virt_to_page(slabp->s_mem)); | 1003 | ClearPageSlabPfmemalloc(virt_to_head_page(slabp->s_mem)); |
1004 | clear_obj_pfmemalloc(&objp); | 1004 | clear_obj_pfmemalloc(&objp); |
1005 | recheck_pfmemalloc_active(cachep, ac); | 1005 | recheck_pfmemalloc_active(cachep, ac); |
1006 | return objp; | 1006 | return objp; |
@@ -1032,7 +1032,7 @@ static void *__ac_put_obj(struct kmem_cache *cachep, struct array_cache *ac, | |||
1032 | { | 1032 | { |
1033 | if (unlikely(pfmemalloc_active)) { | 1033 | if (unlikely(pfmemalloc_active)) { |
1034 | /* Some pfmemalloc slabs exist, check if this is one */ | 1034 | /* Some pfmemalloc slabs exist, check if this is one */ |
1035 | struct page *page = virt_to_page(objp); | 1035 | struct page *page = virt_to_head_page(objp); |
1036 | if (PageSlabPfmemalloc(page)) | 1036 | if (PageSlabPfmemalloc(page)) |
1037 | set_obj_pfmemalloc(&objp); | 1037 | set_obj_pfmemalloc(&objp); |
1038 | } | 1038 | } |
@@ -1524,12 +1524,13 @@ static inline void *acquire_slab(struct kmem_cache *s, | |||
1524 | } | 1524 | } |
1525 | 1525 | ||
1526 | static int put_cpu_partial(struct kmem_cache *s, struct page *page, int drain); | 1526 | static int put_cpu_partial(struct kmem_cache *s, struct page *page, int drain); |
1527 | static inline bool pfmemalloc_match(struct page *page, gfp_t gfpflags); | ||
1527 | 1528 | ||
1528 | /* | 1529 | /* |
1529 | * Try to allocate a partial slab from a specific node. | 1530 | * Try to allocate a partial slab from a specific node. |
1530 | */ | 1531 | */ |
1531 | static void *get_partial_node(struct kmem_cache *s, | 1532 | static void *get_partial_node(struct kmem_cache *s, struct kmem_cache_node *n, |
1532 | struct kmem_cache_node *n, struct kmem_cache_cpu *c) | 1533 | struct kmem_cache_cpu *c, gfp_t flags) |
1533 | { | 1534 | { |
1534 | struct page *page, *page2; | 1535 | struct page *page, *page2; |
1535 | void *object = NULL; | 1536 | void *object = NULL; |
@@ -1545,9 +1546,13 @@ static void *get_partial_node(struct kmem_cache *s, | |||
1545 | 1546 | ||
1546 | spin_lock(&n->list_lock); | 1547 | spin_lock(&n->list_lock); |
1547 | list_for_each_entry_safe(page, page2, &n->partial, lru) { | 1548 | list_for_each_entry_safe(page, page2, &n->partial, lru) { |
1548 | void *t = acquire_slab(s, n, page, object == NULL); | 1549 | void *t; |
1549 | int available; | 1550 | int available; |
1550 | 1551 | ||
1552 | if (!pfmemalloc_match(page, flags)) | ||
1553 | continue; | ||
1554 | |||
1555 | t = acquire_slab(s, n, page, object == NULL); | ||
1551 | if (!t) | 1556 | if (!t) |
1552 | break; | 1557 | break; |
1553 | 1558 | ||
@@ -1614,7 +1619,7 @@ static void *get_any_partial(struct kmem_cache *s, gfp_t flags, | |||
1614 | 1619 | ||
1615 | if (n && cpuset_zone_allowed_hardwall(zone, flags) && | 1620 | if (n && cpuset_zone_allowed_hardwall(zone, flags) && |
1616 | n->nr_partial > s->min_partial) { | 1621 | n->nr_partial > s->min_partial) { |
1617 | object = get_partial_node(s, n, c); | 1622 | object = get_partial_node(s, n, c, flags); |
1618 | if (object) { | 1623 | if (object) { |
1619 | /* | 1624 | /* |
1620 | * Return the object even if | 1625 | * Return the object even if |
@@ -1643,7 +1648,7 @@ static void *get_partial(struct kmem_cache *s, gfp_t flags, int node, | |||
1643 | void *object; | 1648 | void *object; |
1644 | int searchnode = (node == NUMA_NO_NODE) ? numa_node_id() : node; | 1649 | int searchnode = (node == NUMA_NO_NODE) ? numa_node_id() : node; |
1645 | 1650 | ||
1646 | object = get_partial_node(s, get_node(s, searchnode), c); | 1651 | object = get_partial_node(s, get_node(s, searchnode), c, flags); |
1647 | if (object || node != NUMA_NO_NODE) | 1652 | if (object || node != NUMA_NO_NODE) |
1648 | return object; | 1653 | return object; |
1649 | 1654 | ||
diff --git a/mm/vmscan.c b/mm/vmscan.c index 8d01243d9560..99b434b674c0 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c | |||
@@ -3102,6 +3102,7 @@ int kswapd_run(int nid) | |||
3102 | /* failure at boot is fatal */ | 3102 | /* failure at boot is fatal */ |
3103 | BUG_ON(system_state == SYSTEM_BOOTING); | 3103 | BUG_ON(system_state == SYSTEM_BOOTING); |
3104 | printk("Failed to start kswapd on node %d\n",nid); | 3104 | printk("Failed to start kswapd on node %d\n",nid); |
3105 | pgdat->kswapd = NULL; | ||
3105 | ret = -1; | 3106 | ret = -1; |
3106 | } | 3107 | } |
3107 | return ret; | 3108 | return ret; |