]> Git Repo - linux.git/commitdiff
Merge tag 'v4.5-rc6' into core/resources, to resolve conflict
authorIngo Molnar <[email protected]>
Fri, 4 Mar 2016 11:12:08 +0000 (12:12 +0100)
committerIngo Molnar <[email protected]>
Fri, 4 Mar 2016 11:12:08 +0000 (12:12 +0100)
Signed-off-by: Ingo Molnar <[email protected]>
1  2 
arch/mips/kernel/setup.c
include/linux/mm.h
kernel/memremap.c
kernel/resource.c

diff --combined arch/mips/kernel/setup.c
index c745f0ea257734a1d0cb908b0fe69930bb370501,5fdaf8bdcd2ebeed8e31eb7825edd958bfc1c251..4f607341a7938867efc6f0f0646c218bf168421b
@@@ -732,23 -732,21 +732,23 @@@ static void __init resource_init(void
                        end = HIGHMEM_START - 1;
  
                res = alloc_bootmem(sizeof(struct resource));
 +
 +              res->start = start;
 +              res->end = end;
 +              res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
 +
                switch (boot_mem_map.map[i].type) {
                case BOOT_MEM_RAM:
                case BOOT_MEM_INIT_RAM:
                case BOOT_MEM_ROM_DATA:
                        res->name = "System RAM";
 +                      res->flags |= IORESOURCE_SYSRAM;
                        break;
                case BOOT_MEM_RESERVED:
                default:
                        res->name = "reserved";
                }
  
 -              res->start = start;
 -              res->end = end;
 -
 -              res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
                request_resource(&iomem_resource, res);
  
                /*
@@@ -784,6 -782,7 +784,7 @@@ static inline void prefill_possible_map
  void __init setup_arch(char **cmdline_p)
  {
        cpu_probe();
+       mips_cm_probe();
        prom_init();
  
        setup_early_fdc_console();
diff --combined include/linux/mm.h
index cd5a300d33976f4a4df57589eb1dd5437a5c4087,516e149443397dcf712e4e62aca6fb3c78e542b6..2b6e22782699fc26b2f783c2519e0f4bf0c728d8
@@@ -201,11 -201,13 +201,13 @@@ extern unsigned int kobjsize(const voi
  #endif
  
  #ifdef CONFIG_STACK_GROWSUP
- #define VM_STACK_FLAGS        (VM_GROWSUP | VM_STACK_DEFAULT_FLAGS | VM_ACCOUNT)
+ #define VM_STACK      VM_GROWSUP
  #else
- #define VM_STACK_FLAGS        (VM_GROWSDOWN | VM_STACK_DEFAULT_FLAGS | VM_ACCOUNT)
+ #define VM_STACK      VM_GROWSDOWN
  #endif
  
+ #define VM_STACK_FLAGS        (VM_STACK | VM_STACK_DEFAULT_FLAGS | VM_ACCOUNT)
  /*
   * Special vmas that are non-mergable, non-mlock()able.
   * Note: mm/huge_memory.c VM_NO_THP depends on this definition.
@@@ -385,8 -387,7 +387,8 @@@ enum 
        REGION_MIXED,
  };
  
 -int region_intersects(resource_size_t offset, size_t size, const char *type);
 +int region_intersects(resource_size_t offset, size_t size, unsigned long flags,
 +                    unsigned long desc);
  
  /* Support for virtually mapped pages */
  struct page *vmalloc_to_page(const void *addr);
@@@ -1342,8 -1343,7 +1344,7 @@@ static inline int stack_guard_page_end(
                !vma_growsup(vma->vm_next, addr);
  }
  
- extern struct task_struct *task_of_stack(struct task_struct *task,
-                               struct vm_area_struct *vma, bool in_group);
+ int vma_is_stack_for_task(struct vm_area_struct *vma, struct task_struct *t);
  
  extern unsigned long move_page_tables(struct vm_area_struct *vma,
                unsigned long old_addr, struct vm_area_struct *new_vma,
diff --combined kernel/memremap.c
index 293309cac061cf9a83e99075537720ae3e4c2772,b981a7b023f04c356df5b852f60caeae232fdf45..97b31c774274f5009be2facaf4ffb37928944fb0
@@@ -47,7 -47,7 +47,7 @@@ static void *try_ram_remap(resource_siz
   * being mapped does not have i/o side effects and the __iomem
   * annotation is not applicable.
   *
 - * MEMREMAP_WB - matches the default mapping for "System RAM" on
 + * MEMREMAP_WB - matches the default mapping for System RAM on
   * the architecture.  This is usually a read-allocate write-back cache.
   * Morever, if MEMREMAP_WB is specified and the requested remap region is RAM
   * memremap() will bypass establishing a new mapping and instead return
   * MEMREMAP_WT - establish a mapping whereby writes either bypass the
   * cache or are written through to memory and never exist in a
   * cache-dirty state with respect to program visibility.  Attempts to
 - * map "System RAM" with this mapping type will fail.
 + * map System RAM with this mapping type will fail.
   */
  void *memremap(resource_size_t offset, size_t size, unsigned long flags)
  {
 -      int is_ram = region_intersects(offset, size, "System RAM");
 +      int is_ram = region_intersects(offset, size,
 +                                     IORESOURCE_SYSTEM_RAM, IORES_DESC_NONE);
        void *addr = NULL;
  
        if (is_ram == REGION_MIXED) {
@@@ -77,7 -76,7 +77,7 @@@
                 * MEMREMAP_WB is special in that it can be satisifed
                 * from the direct map.  Some archs depend on the
                 * capability of memremap() to autodetect cases where
 -               * the requested range is potentially in "System RAM"
 +               * the requested range is potentially in System RAM.
                 */
                if (is_ram == REGION_INTERSECTS)
                        addr = try_ram_remap(offset, size);
@@@ -89,7 -88,7 +89,7 @@@
         * If we don't have a mapping yet and more request flags are
         * pending then we will be attempting to establish a new virtual
         * address mapping.  Enforce that this mapping is not aliasing
 -       * "System RAM"
 +       * System RAM.
         */
        if (!addr && is_ram == REGION_INTERSECTS && flags) {
                WARN_ONCE(1, "memremap attempted on ram %pa size: %#lx\n",
@@@ -115,7 -114,7 +115,7 @@@ EXPORT_SYMBOL(memunmap)
  
  static void devm_memremap_release(struct device *dev, void *res)
  {
-       memunmap(res);
+       memunmap(*(void **)res);
  }
  
  static int devm_memremap_match(struct device *dev, void *res, void *match_data)
@@@ -137,8 -136,10 +137,10 @@@ void *devm_memremap(struct device *dev
        if (addr) {
                *ptr = addr;
                devres_add(dev, ptr);
-       } else
+       } else {
                devres_free(ptr);
+               return ERR_PTR(-ENXIO);
+       }
  
        return addr;
  }
@@@ -151,7 -152,7 +153,7 @@@ void devm_memunmap(struct device *dev, 
  }
  EXPORT_SYMBOL(devm_memunmap);
  
- pfn_t phys_to_pfn_t(dma_addr_t addr, unsigned long flags)
+ pfn_t phys_to_pfn_t(phys_addr_t addr, u64 flags)
  {
        return __pfn_to_pfn_t(addr >> PAGE_SHIFT, flags);
  }
@@@ -184,7 -185,11 +186,11 @@@ EXPORT_SYMBOL(put_zone_device_page)
  
  static void pgmap_radix_release(struct resource *res)
  {
-       resource_size_t key;
+       resource_size_t key, align_start, align_size, align_end;
+       align_start = res->start & ~(SECTION_SIZE - 1);
+       align_size = ALIGN(resource_size(res), SECTION_SIZE);
+       align_end = align_start + align_size - 1;
  
        mutex_lock(&pgmap_lock);
        for (key = res->start; key <= res->end; key += SECTION_SIZE)
@@@ -227,12 -232,11 +233,11 @@@ static void devm_memremap_pages_release
                percpu_ref_put(pgmap->ref);
        }
  
-       pgmap_radix_release(res);
        /* pages are dead and unused, undo the arch mapping */
        align_start = res->start & ~(SECTION_SIZE - 1);
        align_size = ALIGN(resource_size(res), SECTION_SIZE);
        arch_remove_memory(align_start, align_size);
+       pgmap_radix_release(res);
        dev_WARN_ONCE(dev, pgmap->altmap && pgmap->altmap->alloc,
                        "%s: failed to free all reserved pages\n", __func__);
  }
@@@ -267,8 -271,8 +272,8 @@@ void *devm_memremap_pages(struct devic
                struct percpu_ref *ref, struct vmem_altmap *altmap)
  {
        int is_ram = region_intersects(res->start, resource_size(res),
 -                      "System RAM");
 +                                     IORESOURCE_SYSTEM_RAM, IORES_DESC_NONE);
-       resource_size_t key, align_start, align_size;
+       resource_size_t key, align_start, align_size, align_end;
        struct dev_pagemap *pgmap;
        struct page_map *page_map;
        unsigned long pfn;
  
        mutex_lock(&pgmap_lock);
        error = 0;
-       for (key = res->start; key <= res->end; key += SECTION_SIZE) {
+       align_start = res->start & ~(SECTION_SIZE - 1);
+       align_size = ALIGN(resource_size(res), SECTION_SIZE);
+       align_end = align_start + align_size - 1;
+       for (key = align_start; key <= align_end; key += SECTION_SIZE) {
                struct dev_pagemap *dup;
  
                rcu_read_lock();
        if (nid < 0)
                nid = numa_mem_id();
  
-       align_start = res->start & ~(SECTION_SIZE - 1);
-       align_size = ALIGN(resource_size(res), SECTION_SIZE);
        error = arch_add_memory(nid, align_start, align_size, true);
        if (error)
                goto err_add_memory;
diff --combined kernel/resource.c
index 49834309043c4d639becb95f6ee5c4f6b05d6666,3669d1bfc4254213e0e42dacab374624d74cdd5c..4d466052426b3e993e7e3c3550e948308e377c51
@@@ -333,13 -333,13 +333,13 @@@ int release_resource(struct resource *o
  EXPORT_SYMBOL(release_resource);
  
  /*
 - * Finds the lowest iomem reosurce exists with-in [res->start.res->end)
 - * the caller must specify res->start, res->end, res->flags and "name".
 - * If found, returns 0, res is overwritten, if not found, returns -1.
 - * This walks through whole tree and not just first level children
 - * until and unless first_level_children_only is true.
 + * Finds the lowest iomem resource existing within [res->start.res->end).
 + * The caller must specify res->start, res->end, res->flags, and optionally
 + * desc.  If found, returns 0, res is overwritten, if not found, returns -1.
 + * This function walks the whole tree and not just first level children until
 + * and unless first_level_children_only is true.
   */
 -static int find_next_iomem_res(struct resource *res, char *name,
 +static int find_next_iomem_res(struct resource *res, unsigned long desc,
                               bool first_level_children_only)
  {
        resource_size_t start, end;
        read_lock(&resource_lock);
  
        for (p = iomem_resource.child; p; p = next_resource(p, sibling_only)) {
 -              if (p->flags != res->flags)
 +              if ((p->flags & res->flags) != res->flags)
                        continue;
 -              if (name && strcmp(p->name, name))
 +              if ((desc != IORES_DESC_NONE) && (desc != p->desc))
                        continue;
                if (p->start > end) {
                        p = NULL;
   * Walks through iomem resources and calls func() with matching resource
   * ranges. This walks through whole tree and not just first level children.
   * All the memory ranges which overlap start,end and also match flags and
 - * name are valid candidates.
 + * desc are valid candidates.
   *
 - * @name: name of resource
 - * @flags: resource flags
 + * @desc: I/O resource descriptor. Use IORES_DESC_NONE to skip @desc check.
 + * @flags: I/O resource flags
   * @start: start addr
   * @end: end addr
 + *
 + * NOTE: For a new descriptor search, define a new IORES_DESC in
 + * <linux/ioport.h> and set it in 'desc' of a target resource entry.
   */
 -int walk_iomem_res(char *name, unsigned long flags, u64 start, u64 end,
 -              void *arg, int (*func)(u64, u64, void *))
 +int walk_iomem_res_desc(unsigned long desc, unsigned long flags, u64 start,
 +              u64 end, void *arg, int (*func)(u64, u64, void *))
  {
        struct resource res;
        u64 orig_end;
        res.end = end;
        res.flags = flags;
        orig_end = res.end;
 +
        while ((res.start < res.end) &&
 -              (!find_next_iomem_res(&res, name, false))) {
 +              (!find_next_iomem_res(&res, desc, false))) {
 +
                ret = (*func)(res.start, res.end, arg);
                if (ret)
                        break;
 +
                res.start = res.end + 1;
                res.end = orig_end;
        }
 +
        return ret;
  }
  
  /*
 - * This function calls callback against all memory range of "System RAM"
 - * which are marked as IORESOURCE_MEM and IORESOUCE_BUSY.
 - * Now, this function is only for "System RAM". This function deals with
 - * full ranges and not pfn. If resources are not pfn aligned, dealing
 - * with pfn can truncate ranges.
 + * This function calls the @func callback against all memory ranges of type
 + * System RAM which are marked as IORESOURCE_SYSTEM_RAM and IORESOUCE_BUSY.
 + * Now, this function is only for System RAM, it deals with full ranges and
 + * not PFNs. If resources are not PFN-aligned, dealing with PFNs can truncate
 + * ranges.
   */
  int walk_system_ram_res(u64 start, u64 end, void *arg,
                                int (*func)(u64, u64, void *))
  
        res.start = start;
        res.end = end;
 -      res.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
 +      res.flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
        orig_end = res.end;
        while ((res.start < res.end) &&
 -              (!find_next_iomem_res(&res, "System RAM", true))) {
 +              (!find_next_iomem_res(&res, IORES_DESC_NONE, true))) {
                ret = (*func)(res.start, res.end, arg);
                if (ret)
                        break;
  #if !defined(CONFIG_ARCH_HAS_WALK_MEMORY)
  
  /*
 - * This function calls callback against all memory range of "System RAM"
 - * which are marked as IORESOURCE_MEM and IORESOUCE_BUSY.
 - * Now, this function is only for "System RAM".
 + * This function calls the @func callback against all memory ranges of type
 + * System RAM which are marked as IORESOURCE_SYSTEM_RAM and IORESOUCE_BUSY.
 + * It is to be used only for System RAM.
   */
  int walk_system_ram_range(unsigned long start_pfn, unsigned long nr_pages,
                void *arg, int (*func)(unsigned long, unsigned long, void *))
  
        res.start = (u64) start_pfn << PAGE_SHIFT;
        res.end = ((u64)(start_pfn + nr_pages) << PAGE_SHIFT) - 1;
 -      res.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
 +      res.flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
        orig_end = res.end;
        while ((res.start < res.end) &&
 -              (find_next_iomem_res(&res, "System RAM", true) >= 0)) {
 +              (find_next_iomem_res(&res, IORES_DESC_NONE, true) >= 0)) {
                pfn = (res.start + PAGE_SIZE - 1) >> PAGE_SHIFT;
                end_pfn = (res.end + 1) >> PAGE_SHIFT;
                if (end_pfn > pfn)
@@@ -491,7 -484,7 +491,7 @@@ static int __is_ram(unsigned long pfn, 
  }
  /*
   * This generic page_is_ram() returns true if specified address is
 - * registered as "System RAM" in iomem_resource list.
 + * registered as System RAM in iomem_resource list.
   */
  int __weak page_is_ram(unsigned long pfn)
  {
@@@ -503,34 -496,30 +503,34 @@@ EXPORT_SYMBOL_GPL(page_is_ram)
   * region_intersects() - determine intersection of region with known resources
   * @start: region start address
   * @size: size of region
 - * @name: name of resource (in iomem_resource)
 + * @flags: flags of resource (in iomem_resource)
 + * @desc: descriptor of resource (in iomem_resource) or IORES_DESC_NONE
   *
   * Check if the specified region partially overlaps or fully eclipses a
 - * resource identified by @name.  Return REGION_DISJOINT if the region
 - * does not overlap @name, return REGION_MIXED if the region overlaps
 - * @type and another resource, and return REGION_INTERSECTS if the
 - * region overlaps @type and no other defined resource. Note, that
 - * REGION_INTERSECTS is also returned in the case when the specified
 - * region overlaps RAM and undefined memory holes.
 + * resource identified by @flags and @desc (optional with IORES_DESC_NONE).
 + * Return REGION_DISJOINT if the region does not overlap @flags/@desc,
 + * return REGION_MIXED if the region overlaps @flags/@desc and another
 + * resource, and return REGION_INTERSECTS if the region overlaps @flags/@desc
 + * and no other defined resource. Note that REGION_INTERSECTS is also
 + * returned in the case when the specified region overlaps RAM and undefined
 + * memory holes.
   *
   * region_intersect() is used by memory remapping functions to ensure
   * the user is not remapping RAM and is a vast speed up over walking
   * through the resource table page by page.
   */
 -int region_intersects(resource_size_t start, size_t size, const char *name)
 +int region_intersects(resource_size_t start, size_t size, unsigned long flags,
 +                    unsigned long desc)
  {
 -      unsigned long flags = IORESOURCE_MEM | IORESOURCE_BUSY;
        resource_size_t end = start + size - 1;
        int type = 0; int other = 0;
        struct resource *p;
  
        read_lock(&resource_lock);
        for (p = iomem_resource.child; p ; p = p->sibling) {
 -              bool is_type = strcmp(p->name, name) == 0 && p->flags == flags;
 +              bool is_type = (((p->flags & flags) == flags) &&
 +                              ((desc == IORES_DESC_NONE) ||
 +                               (desc == p->desc)));
  
                if (start >= p->start && start <= p->end)
                        is_type ? type++ : other++;
  
        return REGION_DISJOINT;
  }
 +EXPORT_SYMBOL_GPL(region_intersects);
  
  void __weak arch_remove_reservations(struct resource *avail)
  {
@@@ -960,7 -948,6 +960,7 @@@ static void __init __reserve_region_wit
        res->start = start;
        res->end = end;
        res->flags = IORESOURCE_BUSY;
 +      res->desc = IORES_DESC_NONE;
  
        while (1) {
  
                                next_res->start = conflict->end + 1;
                                next_res->end = end;
                                next_res->flags = IORESOURCE_BUSY;
 +                              next_res->desc = IORES_DESC_NONE;
                        }
                } else {
                        res->start = conflict->end + 1;
@@@ -1085,9 -1071,8 +1085,9 @@@ struct resource * __request_region(stru
        res->name = name;
        res->start = start;
        res->end = start + n - 1;
 -      res->flags = resource_type(parent);
 +      res->flags = resource_type(parent) | resource_ext_type(parent);
        res->flags |= IORESOURCE_BUSY | flags;
 +      res->desc = IORES_DESC_NONE;
  
        write_lock(&resource_lock);
  
                if (!conflict)
                        break;
                if (conflict != parent) {
-                       parent = conflict;
-                       if (!(conflict->flags & IORESOURCE_BUSY))
+                       if (!(conflict->flags & IORESOURCE_BUSY)) {
+                               parent = conflict;
                                continue;
+                       }
                }
                if (conflict->flags & flags & IORESOURCE_MUXED) {
                        add_wait_queue(&muxed_resource_wait, &wait);
@@@ -1252,7 -1238,6 +1253,7 @@@ int release_mem_region_adjustable(struc
                        new_res->start = end + 1;
                        new_res->end = res->end;
                        new_res->flags = res->flags;
 +                      new_res->desc = res->desc;
                        new_res->parent = res->parent;
                        new_res->sibling = res->sibling;
                        new_res->child = NULL;
@@@ -1428,7 -1413,6 +1429,7 @@@ static int __init reserve_setup(char *s
                        res->start = io_start;
                        res->end = io_start + io_num - 1;
                        res->flags = IORESOURCE_BUSY;
 +                      res->desc = IORES_DESC_NONE;
                        res->child = NULL;
                        if (request_resource(res->start >= 0x10000 ? &iomem_resource : &ioport_resource, res) == 0)
                                reserved = x+1;
This page took 0.109175 seconds and 4 git commands to generate.