root/drivers/dax/kmem.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. dev_dax_kmem_probe
  2. dev_dax_kmem_remove
  3. dev_dax_kmem_remove
  4. dax_kmem_init
  5. dax_kmem_exit

   1 // SPDX-License-Identifier: GPL-2.0
   2 /* Copyright(c) 2016-2019 Intel Corporation. All rights reserved. */
   3 #include <linux/memremap.h>
   4 #include <linux/pagemap.h>
   5 #include <linux/memory.h>
   6 #include <linux/module.h>
   7 #include <linux/device.h>
   8 #include <linux/pfn_t.h>
   9 #include <linux/slab.h>
  10 #include <linux/dax.h>
  11 #include <linux/fs.h>
  12 #include <linux/mm.h>
  13 #include <linux/mman.h>
  14 #include "dax-private.h"
  15 #include "bus.h"
  16 
  17 int dev_dax_kmem_probe(struct device *dev)
  18 {
  19         struct dev_dax *dev_dax = to_dev_dax(dev);
  20         struct resource *res = &dev_dax->region->res;
  21         resource_size_t kmem_start;
  22         resource_size_t kmem_size;
  23         resource_size_t kmem_end;
  24         struct resource *new_res;
  25         const char *new_res_name;
  26         int numa_node;
  27         int rc;
  28 
  29         /*
  30          * Ensure good NUMA information for the persistent memory.
  31          * Without this check, there is a risk that slow memory
  32          * could be mixed in a node with faster memory, causing
  33          * unavoidable performance issues.
  34          */
  35         numa_node = dev_dax->target_node;
  36         if (numa_node < 0) {
  37                 dev_warn(dev, "rejecting DAX region %pR with invalid node: %d\n",
  38                          res, numa_node);
  39                 return -EINVAL;
  40         }
  41 
  42         /* Hotplug starting at the beginning of the next block: */
  43         kmem_start = ALIGN(res->start, memory_block_size_bytes());
  44 
  45         kmem_size = resource_size(res);
  46         /* Adjust the size down to compensate for moving up kmem_start: */
  47         kmem_size -= kmem_start - res->start;
  48         /* Align the size down to cover only complete blocks: */
  49         kmem_size &= ~(memory_block_size_bytes() - 1);
  50         kmem_end = kmem_start + kmem_size;
  51 
  52         new_res_name = kstrdup(dev_name(dev), GFP_KERNEL);
  53         if (!new_res_name)
  54                 return -ENOMEM;
  55 
  56         /* Region is permanently reserved if hotremove fails. */
  57         new_res = request_mem_region(kmem_start, kmem_size, new_res_name);
  58         if (!new_res) {
  59                 dev_warn(dev, "could not reserve region [%pa-%pa]\n",
  60                          &kmem_start, &kmem_end);
  61                 kfree(new_res_name);
  62                 return -EBUSY;
  63         }
  64 
  65         /*
  66          * Set flags appropriate for System RAM.  Leave ..._BUSY clear
  67          * so that add_memory() can add a child resource.  Do not
  68          * inherit flags from the parent since it may set new flags
  69          * unknown to us that will break add_memory() below.
  70          */
  71         new_res->flags = IORESOURCE_SYSTEM_RAM;
  72 
  73         rc = add_memory(numa_node, new_res->start, resource_size(new_res));
  74         if (rc) {
  75                 release_resource(new_res);
  76                 kfree(new_res);
  77                 kfree(new_res_name);
  78                 return rc;
  79         }
  80         dev_dax->dax_kmem_res = new_res;
  81 
  82         return 0;
  83 }
  84 
  85 #ifdef CONFIG_MEMORY_HOTREMOVE
  86 static int dev_dax_kmem_remove(struct device *dev)
  87 {
  88         struct dev_dax *dev_dax = to_dev_dax(dev);
  89         struct resource *res = dev_dax->dax_kmem_res;
  90         resource_size_t kmem_start = res->start;
  91         resource_size_t kmem_size = resource_size(res);
  92         const char *res_name = res->name;
  93         int rc;
  94 
  95         /*
  96          * We have one shot for removing memory, if some memory blocks were not
  97          * offline prior to calling this function remove_memory() will fail, and
  98          * there is no way to hotremove this memory until reboot because device
  99          * unbind will succeed even if we return failure.
 100          */
 101         rc = remove_memory(dev_dax->target_node, kmem_start, kmem_size);
 102         if (rc) {
 103                 dev_err(dev,
 104                         "DAX region %pR cannot be hotremoved until the next reboot\n",
 105                         res);
 106                 return rc;
 107         }
 108 
 109         /* Release and free dax resources */
 110         release_resource(res);
 111         kfree(res);
 112         kfree(res_name);
 113         dev_dax->dax_kmem_res = NULL;
 114 
 115         return 0;
 116 }
 117 #else
 118 static int dev_dax_kmem_remove(struct device *dev)
 119 {
 120         /*
 121          * Without hotremove purposely leak the request_mem_region() for the
 122          * device-dax range and return '0' to ->remove() attempts. The removal
 123          * of the device from the driver always succeeds, but the region is
 124          * permanently pinned as reserved by the unreleased
 125          * request_mem_region().
 126          */
 127         return 0;
 128 }
 129 #endif /* CONFIG_MEMORY_HOTREMOVE */
 130 
 131 static struct dax_device_driver device_dax_kmem_driver = {
 132         .drv = {
 133                 .probe = dev_dax_kmem_probe,
 134                 .remove = dev_dax_kmem_remove,
 135         },
 136 };
 137 
 138 static int __init dax_kmem_init(void)
 139 {
 140         return dax_driver_register(&device_dax_kmem_driver);
 141 }
 142 
 143 static void __exit dax_kmem_exit(void)
 144 {
 145         dax_driver_unregister(&device_dax_kmem_driver);
 146 }
 147 
 148 MODULE_AUTHOR("Intel Corporation");
 149 MODULE_LICENSE("GPL v2");
 150 module_init(dax_kmem_init);
 151 module_exit(dax_kmem_exit);
 152 MODULE_ALIAS_DAX_DEVICE(0);

/* [<][>][^][v][top][bottom][index][help] */