1 /* 2 * Copyright(c) 2013-2015 Intel Corporation. All rights reserved. 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of version 2 of the GNU General Public License as 6 * published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope that it will be useful, but 9 * WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 * General Public License for more details. 12 */ 13 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 14 #include <linux/vmalloc.h> 15 #include <linux/device.h> 16 #include <linux/ndctl.h> 17 #include <linux/slab.h> 18 #include <linux/io.h> 19 #include <linux/fs.h> 20 #include <linux/mm.h> 21 #include "nd-core.h" 22 #include "nd.h" 23 24 static DEFINE_IDA(dimm_ida); 25 26 /* 27 * Retrieve bus and dimm handle and return if this bus supports 28 * get_config_data commands 29 */ 30 static int __validate_dimm(struct nvdimm_drvdata *ndd) 31 { 32 struct nvdimm *nvdimm; 33 34 if (!ndd) 35 return -EINVAL; 36 37 nvdimm = to_nvdimm(ndd->dev); 38 39 if (!nvdimm->dsm_mask) 40 return -ENXIO; 41 if (!test_bit(ND_CMD_GET_CONFIG_DATA, nvdimm->dsm_mask)) 42 return -ENXIO; 43 44 return 0; 45 } 46 47 static int validate_dimm(struct nvdimm_drvdata *ndd) 48 { 49 int rc = __validate_dimm(ndd); 50 51 if (rc && ndd) 52 dev_dbg(ndd->dev, "%pf: %s error: %d\n", 53 __builtin_return_address(0), __func__, rc); 54 return rc; 55 } 56 57 /** 58 * nvdimm_init_nsarea - determine the geometry of a dimm's namespace area 59 * @nvdimm: dimm to initialize 60 */ 61 int nvdimm_init_nsarea(struct nvdimm_drvdata *ndd) 62 { 63 struct nd_cmd_get_config_size *cmd = &ndd->nsarea; 64 struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(ndd->dev); 65 struct nvdimm_bus_descriptor *nd_desc; 66 int rc = validate_dimm(ndd); 67 68 if (rc) 69 return rc; 70 71 if (cmd->config_size) 72 return 0; /* already valid */ 73 74 memset(cmd, 0, sizeof(*cmd)); 75 nd_desc = nvdimm_bus->nd_desc; 76 return nd_desc->ndctl(nd_desc, to_nvdimm(ndd->dev), 77 ND_CMD_GET_CONFIG_SIZE, cmd, sizeof(*cmd)); 78 } 79 80 int nvdimm_init_config_data(struct nvdimm_drvdata *ndd) 81 { 82 struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(ndd->dev); 83 struct nd_cmd_get_config_data_hdr *cmd; 84 struct nvdimm_bus_descriptor *nd_desc; 85 int rc = validate_dimm(ndd); 86 u32 max_cmd_size, config_size; 87 size_t offset; 88 89 if (rc) 90 return rc; 91 92 if (ndd->data) 93 return 0; 94 95 if (ndd->nsarea.status || ndd->nsarea.max_xfer == 0 96 || ndd->nsarea.config_size < ND_LABEL_MIN_SIZE) { 97 dev_dbg(ndd->dev, "failed to init config data area: (%d:%d)\n", 98 ndd->nsarea.max_xfer, ndd->nsarea.config_size); 99 return -ENXIO; 100 } 101 102 ndd->data = kmalloc(ndd->nsarea.config_size, GFP_KERNEL); 103 if (!ndd->data) 104 ndd->data = vmalloc(ndd->nsarea.config_size); 105 106 if (!ndd->data) 107 return -ENOMEM; 108 109 max_cmd_size = min_t(u32, PAGE_SIZE, ndd->nsarea.max_xfer); 110 cmd = kzalloc(max_cmd_size + sizeof(*cmd), GFP_KERNEL); 111 if (!cmd) 112 return -ENOMEM; 113 114 nd_desc = nvdimm_bus->nd_desc; 115 for (config_size = ndd->nsarea.config_size, offset = 0; 116 config_size; config_size -= cmd->in_length, 117 offset += cmd->in_length) { 118 cmd->in_length = min(config_size, max_cmd_size); 119 cmd->in_offset = offset; 120 rc = nd_desc->ndctl(nd_desc, to_nvdimm(ndd->dev), 121 ND_CMD_GET_CONFIG_DATA, cmd, 122 cmd->in_length + sizeof(*cmd)); 123 if (rc || cmd->status) { 124 rc = -ENXIO; 125 break; 126 } 127 memcpy(ndd->data + offset, cmd->out_buf, cmd->in_length); 128 } 129 dev_dbg(ndd->dev, "%s: len: %zu rc: %d\n", __func__, offset, rc); 130 kfree(cmd); 131 132 return rc; 133 } 134 135 static void nvdimm_release(struct device *dev) 136 { 137 struct nvdimm *nvdimm = to_nvdimm(dev); 138 139 ida_simple_remove(&dimm_ida, nvdimm->id); 140 kfree(nvdimm); 141 } 142 143 static struct device_type nvdimm_device_type = { 144 .name = "nvdimm", 145 .release = nvdimm_release, 146 }; 147 148 bool is_nvdimm(struct device *dev) 149 { 150 return dev->type == &nvdimm_device_type; 151 } 152 153 struct nvdimm *to_nvdimm(struct device *dev) 154 { 155 struct nvdimm *nvdimm = container_of(dev, struct nvdimm, dev); 156 157 WARN_ON(!is_nvdimm(dev)); 158 return nvdimm; 159 } 160 EXPORT_SYMBOL_GPL(to_nvdimm); 161 162 struct nvdimm_drvdata *to_ndd(struct nd_mapping *nd_mapping) 163 { 164 struct nvdimm *nvdimm = nd_mapping->nvdimm; 165 166 WARN_ON_ONCE(!is_nvdimm_bus_locked(&nvdimm->dev)); 167 168 return dev_get_drvdata(&nvdimm->dev); 169 } 170 EXPORT_SYMBOL(to_ndd); 171 172 void nvdimm_drvdata_release(struct kref *kref) 173 { 174 struct nvdimm_drvdata *ndd = container_of(kref, typeof(*ndd), kref); 175 struct device *dev = ndd->dev; 176 struct resource *res, *_r; 177 178 dev_dbg(dev, "%s\n", __func__); 179 180 nvdimm_bus_lock(dev); 181 for_each_dpa_resource_safe(ndd, res, _r) 182 nvdimm_free_dpa(ndd, res); 183 nvdimm_bus_unlock(dev); 184 185 if (ndd->data && is_vmalloc_addr(ndd->data)) 186 vfree(ndd->data); 187 else 188 kfree(ndd->data); 189 kfree(ndd); 190 put_device(dev); 191 } 192 193 void get_ndd(struct nvdimm_drvdata *ndd) 194 { 195 kref_get(&ndd->kref); 196 } 197 198 void put_ndd(struct nvdimm_drvdata *ndd) 199 { 200 if (ndd) 201 kref_put(&ndd->kref, nvdimm_drvdata_release); 202 } 203 204 const char *nvdimm_name(struct nvdimm *nvdimm) 205 { 206 return dev_name(&nvdimm->dev); 207 } 208 EXPORT_SYMBOL_GPL(nvdimm_name); 209 210 void *nvdimm_provider_data(struct nvdimm *nvdimm) 211 { 212 if (nvdimm) 213 return nvdimm->provider_data; 214 return NULL; 215 } 216 EXPORT_SYMBOL_GPL(nvdimm_provider_data); 217 218 static ssize_t commands_show(struct device *dev, 219 struct device_attribute *attr, char *buf) 220 { 221 struct nvdimm *nvdimm = to_nvdimm(dev); 222 int cmd, len = 0; 223 224 if (!nvdimm->dsm_mask) 225 return sprintf(buf, "\n"); 226 227 for_each_set_bit(cmd, nvdimm->dsm_mask, BITS_PER_LONG) 228 len += sprintf(buf + len, "%s ", nvdimm_cmd_name(cmd)); 229 len += sprintf(buf + len, "\n"); 230 return len; 231 } 232 static DEVICE_ATTR_RO(commands); 233 234 static ssize_t state_show(struct device *dev, struct device_attribute *attr, 235 char *buf) 236 { 237 struct nvdimm *nvdimm = to_nvdimm(dev); 238 239 /* 240 * The state may be in the process of changing, userspace should 241 * quiesce probing if it wants a static answer 242 */ 243 nvdimm_bus_lock(dev); 244 nvdimm_bus_unlock(dev); 245 return sprintf(buf, "%s\n", atomic_read(&nvdimm->busy) 246 ? "active" : "idle"); 247 } 248 static DEVICE_ATTR_RO(state); 249 250 static struct attribute *nvdimm_attributes[] = { 251 &dev_attr_state.attr, 252 &dev_attr_commands.attr, 253 NULL, 254 }; 255 256 struct attribute_group nvdimm_attribute_group = { 257 .attrs = nvdimm_attributes, 258 }; 259 EXPORT_SYMBOL_GPL(nvdimm_attribute_group); 260 261 struct nvdimm *nvdimm_create(struct nvdimm_bus *nvdimm_bus, void *provider_data, 262 const struct attribute_group **groups, unsigned long flags, 263 unsigned long *dsm_mask) 264 { 265 struct nvdimm *nvdimm = kzalloc(sizeof(*nvdimm), GFP_KERNEL); 266 struct device *dev; 267 268 if (!nvdimm) 269 return NULL; 270 271 nvdimm->id = ida_simple_get(&dimm_ida, 0, 0, GFP_KERNEL); 272 if (nvdimm->id < 0) { 273 kfree(nvdimm); 274 return NULL; 275 } 276 nvdimm->provider_data = provider_data; 277 nvdimm->flags = flags; 278 nvdimm->dsm_mask = dsm_mask; 279 atomic_set(&nvdimm->busy, 0); 280 dev = &nvdimm->dev; 281 dev_set_name(dev, "nmem%d", nvdimm->id); 282 dev->parent = &nvdimm_bus->dev; 283 dev->type = &nvdimm_device_type; 284 dev->devt = MKDEV(nvdimm_major, nvdimm->id); 285 dev->groups = groups; 286 nd_device_register(dev); 287 288 return nvdimm; 289 } 290 EXPORT_SYMBOL_GPL(nvdimm_create); 291 292 /** 293 * nd_blk_available_dpa - account the unused dpa of BLK region 294 * @nd_mapping: container of dpa-resource-root + labels 295 * 296 * Unlike PMEM, BLK namespaces can occupy discontiguous DPA ranges. 297 */ 298 resource_size_t nd_blk_available_dpa(struct nd_mapping *nd_mapping) 299 { 300 struct nvdimm_drvdata *ndd = to_ndd(nd_mapping); 301 resource_size_t map_end, busy = 0, available; 302 struct resource *res; 303 304 if (!ndd) 305 return 0; 306 307 map_end = nd_mapping->start + nd_mapping->size - 1; 308 for_each_dpa_resource(ndd, res) 309 if (res->start >= nd_mapping->start && res->start < map_end) { 310 resource_size_t end = min(map_end, res->end); 311 312 busy += end - res->start + 1; 313 } else if (res->end >= nd_mapping->start 314 && res->end <= map_end) { 315 busy += res->end - nd_mapping->start; 316 } else if (nd_mapping->start > res->start 317 && nd_mapping->start < res->end) { 318 /* total eclipse of the BLK region mapping */ 319 busy += nd_mapping->size; 320 } 321 322 available = map_end - nd_mapping->start + 1; 323 if (busy < available) 324 return available - busy; 325 return 0; 326 } 327 328 /** 329 * nd_pmem_available_dpa - for the given dimm+region account unallocated dpa 330 * @nd_mapping: container of dpa-resource-root + labels 331 * @nd_region: constrain available space check to this reference region 332 * @overlap: calculate available space assuming this level of overlap 333 * 334 * Validate that a PMEM label, if present, aligns with the start of an 335 * interleave set and truncate the available size at the lowest BLK 336 * overlap point. 337 * 338 * The expectation is that this routine is called multiple times as it 339 * probes for the largest BLK encroachment for any single member DIMM of 340 * the interleave set. Once that value is determined the PMEM-limit for 341 * the set can be established. 342 */ 343 resource_size_t nd_pmem_available_dpa(struct nd_region *nd_region, 344 struct nd_mapping *nd_mapping, resource_size_t *overlap) 345 { 346 resource_size_t map_start, map_end, busy = 0, available, blk_start; 347 struct nvdimm_drvdata *ndd = to_ndd(nd_mapping); 348 struct resource *res; 349 const char *reason; 350 351 if (!ndd) 352 return 0; 353 354 map_start = nd_mapping->start; 355 map_end = map_start + nd_mapping->size - 1; 356 blk_start = max(map_start, map_end + 1 - *overlap); 357 for_each_dpa_resource(ndd, res) 358 if (res->start >= map_start && res->start < map_end) { 359 if (strncmp(res->name, "blk", 3) == 0) 360 blk_start = min(blk_start, res->start); 361 else if (res->start != map_start) { 362 reason = "misaligned to iset"; 363 goto err; 364 } else { 365 if (busy) { 366 reason = "duplicate overlapping PMEM reservations?"; 367 goto err; 368 } 369 busy += resource_size(res); 370 continue; 371 } 372 } else if (res->end >= map_start && res->end <= map_end) { 373 if (strncmp(res->name, "blk", 3) == 0) { 374 /* 375 * If a BLK allocation overlaps the start of 376 * PMEM the entire interleave set may now only 377 * be used for BLK. 378 */ 379 blk_start = map_start; 380 } else { 381 reason = "misaligned to iset"; 382 goto err; 383 } 384 } else if (map_start > res->start && map_start < res->end) { 385 /* total eclipse of the mapping */ 386 busy += nd_mapping->size; 387 blk_start = map_start; 388 } 389 390 *overlap = map_end + 1 - blk_start; 391 available = blk_start - map_start; 392 if (busy < available) 393 return available - busy; 394 return 0; 395 396 err: 397 /* 398 * Something is wrong, PMEM must align with the start of the 399 * interleave set, and there can only be one allocation per set. 400 */ 401 nd_dbg_dpa(nd_region, ndd, res, "%s\n", reason); 402 return 0; 403 } 404 405 void nvdimm_free_dpa(struct nvdimm_drvdata *ndd, struct resource *res) 406 { 407 WARN_ON_ONCE(!is_nvdimm_bus_locked(ndd->dev)); 408 kfree(res->name); 409 __release_region(&ndd->dpa, res->start, resource_size(res)); 410 } 411 412 struct resource *nvdimm_allocate_dpa(struct nvdimm_drvdata *ndd, 413 struct nd_label_id *label_id, resource_size_t start, 414 resource_size_t n) 415 { 416 char *name = kmemdup(label_id, sizeof(*label_id), GFP_KERNEL); 417 struct resource *res; 418 419 if (!name) 420 return NULL; 421 422 WARN_ON_ONCE(!is_nvdimm_bus_locked(ndd->dev)); 423 res = __request_region(&ndd->dpa, start, n, name, 0); 424 if (!res) 425 kfree(name); 426 return res; 427 } 428 429 /** 430 * nvdimm_allocated_dpa - sum up the dpa currently allocated to this label_id 431 * @nvdimm: container of dpa-resource-root + labels 432 * @label_id: dpa resource name of the form {pmem|blk}-<human readable uuid> 433 */ 434 resource_size_t nvdimm_allocated_dpa(struct nvdimm_drvdata *ndd, 435 struct nd_label_id *label_id) 436 { 437 resource_size_t allocated = 0; 438 struct resource *res; 439 440 for_each_dpa_resource(ndd, res) 441 if (strcmp(res->name, label_id->id) == 0) 442 allocated += resource_size(res); 443 444 return allocated; 445 } 446 447 static int count_dimms(struct device *dev, void *c) 448 { 449 int *count = c; 450 451 if (is_nvdimm(dev)) 452 (*count)++; 453 return 0; 454 } 455 456 int nvdimm_bus_check_dimm_count(struct nvdimm_bus *nvdimm_bus, int dimm_count) 457 { 458 int count = 0; 459 /* Flush any possible dimm registration failures */ 460 nd_synchronize(); 461 462 device_for_each_child(&nvdimm_bus->dev, &count, count_dimms); 463 dev_dbg(&nvdimm_bus->dev, "%s: count: %d\n", __func__, count); 464 if (count != dimm_count) 465 return -ENXIO; 466 return 0; 467 } 468 EXPORT_SYMBOL_GPL(nvdimm_bus_check_dimm_count); 469