diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-10-09 22:26:14 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-10-09 22:26:14 -0400 |
| commit | 0cf744bc7ae8e0072159a901f6e1a159bbc30ffa (patch) | |
| tree | fc8222a3a5af4f42226070c3f76462cfcf0b4e50 /drivers/base | |
| parent | b528392669415dc1e53a047215e5ad6c2de879fc (diff) | |
| parent | 7f8998c7aef3ac9c5f3f2943e083dfa6302e90d0 (diff) | |
Merge branch 'akpm' (fixes from Andrew Morton)
Merge patch-bomb from Andrew Morton:
- part of OCFS2 (review is laggy again)
- procfs
- slab
- all of MM
- zram, zbud
- various other random things: arch, filesystems.
* emailed patches from Andrew Morton <akpm@linux-foundation.org>: (164 commits)
nosave: consolidate __nosave_{begin,end} in <asm/sections.h>
include/linux/screen_info.h: remove unused ORIG_* macros
kernel/sys.c: compat sysinfo syscall: fix undefined behavior
kernel/sys.c: whitespace fixes
acct: eliminate compile warning
kernel/async.c: switch to pr_foo()
include/linux/blkdev.h: use NULL instead of zero
include/linux/kernel.h: deduplicate code implementing clamp* macros
include/linux/kernel.h: rewrite min3, max3 and clamp using min and max
alpha: use Kbuild logic to include <asm-generic/sections.h>
frv: remove deprecated IRQF_DISABLED
frv: remove unused cpuinfo_frv and friends to fix future build error
zbud: avoid accessing last unused freelist
zsmalloc: simplify init_zspage free obj linking
mm/zsmalloc.c: correct comment for fullness group computation
zram: use notify_free to account all free notifications
zram: report maximum used memory
zram: zram memory size limitation
zsmalloc: change return value unit of zs_get_total_size_bytes
zsmalloc: move pages_allocated to zs_pool
...
Diffstat (limited to 'drivers/base')
| -rw-r--r-- | drivers/base/Kconfig | 3 | ||||
| -rw-r--r-- | drivers/base/dma-mapping.c | 72 | ||||
| -rw-r--r-- | drivers/base/memory.c | 42 | ||||
| -rw-r--r-- | drivers/base/node.c | 3 |
4 files changed, 117 insertions, 3 deletions
diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig index 134f763d90fd..61a33f4ba608 100644 --- a/drivers/base/Kconfig +++ b/drivers/base/Kconfig | |||
| @@ -252,6 +252,9 @@ config DMA_CMA | |||
| 252 | to allocate big physically-contiguous blocks of memory for use with | 252 | to allocate big physically-contiguous blocks of memory for use with |
| 253 | hardware components that do not support I/O map nor scatter-gather. | 253 | hardware components that do not support I/O map nor scatter-gather. |
| 254 | 254 | ||
| 255 | You can disable CMA by specifying "cma=0" on the kernel's command | ||
| 256 | line. | ||
| 257 | |||
| 255 | For more information see <include/linux/dma-contiguous.h>. | 258 | For more information see <include/linux/dma-contiguous.h>. |
| 256 | If unsure, say "n". | 259 | If unsure, say "n". |
| 257 | 260 | ||
diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c index 6cd08e145bfa..9e8bbdd470ca 100644 --- a/drivers/base/dma-mapping.c +++ b/drivers/base/dma-mapping.c | |||
| @@ -10,6 +10,8 @@ | |||
| 10 | #include <linux/dma-mapping.h> | 10 | #include <linux/dma-mapping.h> |
| 11 | #include <linux/export.h> | 11 | #include <linux/export.h> |
| 12 | #include <linux/gfp.h> | 12 | #include <linux/gfp.h> |
| 13 | #include <linux/slab.h> | ||
| 14 | #include <linux/vmalloc.h> | ||
| 13 | #include <asm-generic/dma-coherent.h> | 15 | #include <asm-generic/dma-coherent.h> |
| 14 | 16 | ||
| 15 | /* | 17 | /* |
| @@ -267,3 +269,73 @@ int dma_common_mmap(struct device *dev, struct vm_area_struct *vma, | |||
| 267 | return ret; | 269 | return ret; |
| 268 | } | 270 | } |
| 269 | EXPORT_SYMBOL(dma_common_mmap); | 271 | EXPORT_SYMBOL(dma_common_mmap); |
| 272 | |||
| 273 | #ifdef CONFIG_MMU | ||
| 274 | /* | ||
| 275 | * remaps an array of PAGE_SIZE pages into another vm_area | ||
| 276 | * Cannot be used in non-sleeping contexts | ||
| 277 | */ | ||
| 278 | void *dma_common_pages_remap(struct page **pages, size_t size, | ||
| 279 | unsigned long vm_flags, pgprot_t prot, | ||
| 280 | const void *caller) | ||
| 281 | { | ||
| 282 | struct vm_struct *area; | ||
| 283 | |||
| 284 | area = get_vm_area_caller(size, vm_flags, caller); | ||
| 285 | if (!area) | ||
| 286 | return NULL; | ||
| 287 | |||
| 288 | area->pages = pages; | ||
| 289 | |||
| 290 | if (map_vm_area(area, prot, pages)) { | ||
| 291 | vunmap(area->addr); | ||
| 292 | return NULL; | ||
| 293 | } | ||
| 294 | |||
| 295 | return area->addr; | ||
| 296 | } | ||
| 297 | |||
| 298 | /* | ||
| 299 | * remaps an allocated contiguous region into another vm_area. | ||
| 300 | * Cannot be used in non-sleeping contexts | ||
| 301 | */ | ||
| 302 | |||
| 303 | void *dma_common_contiguous_remap(struct page *page, size_t size, | ||
| 304 | unsigned long vm_flags, | ||
| 305 | pgprot_t prot, const void *caller) | ||
| 306 | { | ||
| 307 | int i; | ||
| 308 | struct page **pages; | ||
| 309 | void *ptr; | ||
| 310 | unsigned long pfn; | ||
| 311 | |||
| 312 | pages = kmalloc(sizeof(struct page *) << get_order(size), GFP_KERNEL); | ||
| 313 | if (!pages) | ||
| 314 | return NULL; | ||
| 315 | |||
| 316 | for (i = 0, pfn = page_to_pfn(page); i < (size >> PAGE_SHIFT); i++) | ||
| 317 | pages[i] = pfn_to_page(pfn + i); | ||
| 318 | |||
| 319 | ptr = dma_common_pages_remap(pages, size, vm_flags, prot, caller); | ||
| 320 | |||
| 321 | kfree(pages); | ||
| 322 | |||
| 323 | return ptr; | ||
| 324 | } | ||
| 325 | |||
| 326 | /* | ||
| 327 | * unmaps a range previously mapped by dma_common_*_remap | ||
| 328 | */ | ||
| 329 | void dma_common_free_remap(void *cpu_addr, size_t size, unsigned long vm_flags) | ||
| 330 | { | ||
| 331 | struct vm_struct *area = find_vm_area(cpu_addr); | ||
| 332 | |||
| 333 | if (!area || (area->flags & vm_flags) != vm_flags) { | ||
| 334 | WARN(1, "trying to free invalid coherent area: %p\n", cpu_addr); | ||
| 335 | return; | ||
| 336 | } | ||
| 337 | |||
| 338 | unmap_kernel_range((unsigned long)cpu_addr, size); | ||
| 339 | vunmap(cpu_addr); | ||
| 340 | } | ||
| 341 | #endif | ||
diff --git a/drivers/base/memory.c b/drivers/base/memory.c index a2e13e250bba..7c5d87191b28 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c | |||
| @@ -373,6 +373,45 @@ static ssize_t show_phys_device(struct device *dev, | |||
| 373 | return sprintf(buf, "%d\n", mem->phys_device); | 373 | return sprintf(buf, "%d\n", mem->phys_device); |
| 374 | } | 374 | } |
| 375 | 375 | ||
| 376 | #ifdef CONFIG_MEMORY_HOTREMOVE | ||
| 377 | static ssize_t show_valid_zones(struct device *dev, | ||
| 378 | struct device_attribute *attr, char *buf) | ||
| 379 | { | ||
| 380 | struct memory_block *mem = to_memory_block(dev); | ||
| 381 | unsigned long start_pfn, end_pfn; | ||
| 382 | unsigned long nr_pages = PAGES_PER_SECTION * sections_per_block; | ||
| 383 | struct page *first_page; | ||
| 384 | struct zone *zone; | ||
| 385 | |||
| 386 | start_pfn = section_nr_to_pfn(mem->start_section_nr); | ||
| 387 | end_pfn = start_pfn + nr_pages; | ||
| 388 | first_page = pfn_to_page(start_pfn); | ||
| 389 | |||
| 390 | /* The block contains more than one zone can not be offlined. */ | ||
| 391 | if (!test_pages_in_a_zone(start_pfn, end_pfn)) | ||
| 392 | return sprintf(buf, "none\n"); | ||
| 393 | |||
| 394 | zone = page_zone(first_page); | ||
| 395 | |||
| 396 | if (zone_idx(zone) == ZONE_MOVABLE - 1) { | ||
| 397 | /*The mem block is the last memoryblock of this zone.*/ | ||
| 398 | if (end_pfn == zone_end_pfn(zone)) | ||
| 399 | return sprintf(buf, "%s %s\n", | ||
| 400 | zone->name, (zone + 1)->name); | ||
| 401 | } | ||
| 402 | |||
| 403 | if (zone_idx(zone) == ZONE_MOVABLE) { | ||
| 404 | /*The mem block is the first memoryblock of ZONE_MOVABLE.*/ | ||
| 405 | if (start_pfn == zone->zone_start_pfn) | ||
| 406 | return sprintf(buf, "%s %s\n", | ||
| 407 | zone->name, (zone - 1)->name); | ||
| 408 | } | ||
| 409 | |||
| 410 | return sprintf(buf, "%s\n", zone->name); | ||
| 411 | } | ||
| 412 | static DEVICE_ATTR(valid_zones, 0444, show_valid_zones, NULL); | ||
| 413 | #endif | ||
| 414 | |||
| 376 | static DEVICE_ATTR(phys_index, 0444, show_mem_start_phys_index, NULL); | 415 | static DEVICE_ATTR(phys_index, 0444, show_mem_start_phys_index, NULL); |
| 377 | static DEVICE_ATTR(state, 0644, show_mem_state, store_mem_state); | 416 | static DEVICE_ATTR(state, 0644, show_mem_state, store_mem_state); |
| 378 | static DEVICE_ATTR(phys_device, 0444, show_phys_device, NULL); | 417 | static DEVICE_ATTR(phys_device, 0444, show_phys_device, NULL); |
| @@ -523,6 +562,9 @@ static struct attribute *memory_memblk_attrs[] = { | |||
| 523 | &dev_attr_state.attr, | 562 | &dev_attr_state.attr, |
| 524 | &dev_attr_phys_device.attr, | 563 | &dev_attr_phys_device.attr, |
| 525 | &dev_attr_removable.attr, | 564 | &dev_attr_removable.attr, |
| 565 | #ifdef CONFIG_MEMORY_HOTREMOVE | ||
| 566 | &dev_attr_valid_zones.attr, | ||
| 567 | #endif | ||
| 526 | NULL | 568 | NULL |
| 527 | }; | 569 | }; |
| 528 | 570 | ||
diff --git a/drivers/base/node.c b/drivers/base/node.c index d51c49c9bafa..472168cd0c97 100644 --- a/drivers/base/node.c +++ b/drivers/base/node.c | |||
| @@ -289,8 +289,6 @@ static int register_node(struct node *node, int num, struct node *parent) | |||
| 289 | device_create_file(&node->dev, &dev_attr_distance); | 289 | device_create_file(&node->dev, &dev_attr_distance); |
| 290 | device_create_file(&node->dev, &dev_attr_vmstat); | 290 | device_create_file(&node->dev, &dev_attr_vmstat); |
| 291 | 291 | ||
| 292 | scan_unevictable_register_node(node); | ||
| 293 | |||
| 294 | hugetlb_register_node(node); | 292 | hugetlb_register_node(node); |
| 295 | 293 | ||
| 296 | compaction_register_node(node); | 294 | compaction_register_node(node); |
| @@ -314,7 +312,6 @@ void unregister_node(struct node *node) | |||
| 314 | device_remove_file(&node->dev, &dev_attr_distance); | 312 | device_remove_file(&node->dev, &dev_attr_distance); |
| 315 | device_remove_file(&node->dev, &dev_attr_vmstat); | 313 | device_remove_file(&node->dev, &dev_attr_vmstat); |
| 316 | 314 | ||
| 317 | scan_unevictable_unregister_node(node); | ||
| 318 | hugetlb_unregister_node(node); /* no-op, if memoryless node */ | 315 | hugetlb_unregister_node(node); /* no-op, if memoryless node */ |
| 319 | 316 | ||
| 320 | device_unregister(&node->dev); | 317 | device_unregister(&node->dev); |
