]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - drivers/dax/kmem.c
ALSA: sparc: Constify snd_kcontrol_new items
[linux.git] / drivers / dax / kmem.c
index a02318c6d28ab85dd45083b6adf72c185ac06fe6..3d0a7e702c94c97d9ef74a5ee158fc55d152fc70 100644 (file)
@@ -66,23 +66,59 @@ int dev_dax_kmem_probe(struct device *dev)
        new_res->name = dev_name(dev);
 
        rc = add_memory(numa_node, new_res->start, resource_size(new_res));
-       if (rc)
+       if (rc) {
+               release_resource(new_res);
+               kfree(new_res);
                return rc;
+       }
+       dev_dax->dax_kmem_res = new_res;
 
        return 0;
 }
 
+#ifdef CONFIG_MEMORY_HOTREMOVE
+static int dev_dax_kmem_remove(struct device *dev)
+{
+       struct dev_dax *dev_dax = to_dev_dax(dev);
+       struct resource *res = dev_dax->dax_kmem_res;
+       resource_size_t kmem_start = res->start;
+       resource_size_t kmem_size = resource_size(res);
+       int rc;
+
+       /*
+        * We have one shot for removing memory, if some memory blocks were not
+        * offline prior to calling this function remove_memory() will fail, and
+        * there is no way to hotremove this memory until reboot because device
+        * unbind will succeed even if we return failure.
+        */
+       rc = remove_memory(dev_dax->target_node, kmem_start, kmem_size);
+       if (rc) {
+               dev_err(dev,
+                       "DAX region %pR cannot be hotremoved until the next reboot\n",
+                       res);
+               return rc;
+       }
+
+       /* Release and free dax resources */
+       release_resource(res);
+       kfree(res);
+       dev_dax->dax_kmem_res = NULL;
+
+       return 0;
+}
+#else
 static int dev_dax_kmem_remove(struct device *dev)
 {
        /*
-        * Purposely leak the request_mem_region() for the device-dax
-        * range and return '0' to ->remove() attempts. The removal of
-        * the device from the driver always succeeds, but the region
-        * is permanently pinned as reserved by the unreleased
+        * Without hotremove purposely leak the request_mem_region() for the
+        * device-dax range and return '0' to ->remove() attempts. The removal
+        * of the device from the driver always succeeds, but the region is
+        * permanently pinned as reserved by the unreleased
         * request_mem_region().
         */
        return 0;
 }
+#endif /* CONFIG_MEMORY_HOTREMOVE */
 
 static struct dax_device_driver device_dax_kmem_driver = {
        .drv = {