memory.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749
  1. /*
  2. * Memory subsystem support
  3. *
  4. * Written by Matt Tolentino <matthew.e.tolentino@intel.com>
  5. * Dave Hansen <haveblue@us.ibm.com>
  6. *
  7. * This file provides the necessary infrastructure to represent
  8. * a SPARSEMEM-memory-model system's physical memory in /sysfs.
  9. * All arch-independent code that assumes MEMORY_HOTPLUG requires
  10. * SPARSEMEM should be contained here, or in mm/memory_hotplug.c.
  11. */
  12. #include <linux/module.h>
  13. #include <linux/init.h>
  14. #include <linux/topology.h>
  15. #include <linux/capability.h>
  16. #include <linux/device.h>
  17. #include <linux/memory.h>
  18. #include <linux/kobject.h>
  19. #include <linux/memory_hotplug.h>
  20. #include <linux/mm.h>
  21. #include <linux/mutex.h>
  22. #include <linux/stat.h>
  23. #include <linux/slab.h>
  24. #include <linux/atomic.h>
  25. #include <asm/uaccess.h>
  26. static DEFINE_MUTEX(mem_sysfs_mutex);
  27. #define MEMORY_CLASS_NAME "memory"
  28. static int sections_per_block;
  29. static inline int base_memory_block_id(int section_nr)
  30. {
  31. return section_nr / sections_per_block;
  32. }
  33. static struct bus_type memory_subsys = {
  34. .name = MEMORY_CLASS_NAME,
  35. .dev_name = MEMORY_CLASS_NAME,
  36. };
  37. static BLOCKING_NOTIFIER_HEAD(memory_chain);
  38. int register_memory_notifier(struct notifier_block *nb)
  39. {
  40. return blocking_notifier_chain_register(&memory_chain, nb);
  41. }
  42. EXPORT_SYMBOL(register_memory_notifier);
  43. void unregister_memory_notifier(struct notifier_block *nb)
  44. {
  45. blocking_notifier_chain_unregister(&memory_chain, nb);
  46. }
  47. EXPORT_SYMBOL(unregister_memory_notifier);
  48. static ATOMIC_NOTIFIER_HEAD(memory_isolate_chain);
  49. int register_memory_isolate_notifier(struct notifier_block *nb)
  50. {
  51. return atomic_notifier_chain_register(&memory_isolate_chain, nb);
  52. }
  53. EXPORT_SYMBOL(register_memory_isolate_notifier);
  54. void unregister_memory_isolate_notifier(struct notifier_block *nb)
  55. {
  56. atomic_notifier_chain_unregister(&memory_isolate_chain, nb);
  57. }
  58. EXPORT_SYMBOL(unregister_memory_isolate_notifier);
  59. static void memory_block_release(struct device *dev)
  60. {
  61. struct memory_block *mem = container_of(dev, struct memory_block, dev);
  62. kfree(mem);
  63. }
  64. /*
  65. * register_memory - Setup a sysfs device for a memory block
  66. */
  67. static
  68. int register_memory(struct memory_block *memory)
  69. {
  70. int error;
  71. memory->dev.bus = &memory_subsys;
  72. memory->dev.id = memory->start_section_nr / sections_per_block;
  73. memory->dev.release = memory_block_release;
  74. error = device_register(&memory->dev);
  75. return error;
  76. }
  77. static void
  78. unregister_memory(struct memory_block *memory)
  79. {
  80. BUG_ON(memory->dev.bus != &memory_subsys);
  81. /* drop the ref. we got in remove_memory_block() */
  82. kobject_put(&memory->dev.kobj);
  83. device_unregister(&memory->dev);
  84. }
  85. unsigned long __weak memory_block_size_bytes(void)
  86. {
  87. return MIN_MEMORY_BLOCK_SIZE;
  88. }
  89. static unsigned long get_memory_block_size(void)
  90. {
  91. unsigned long block_sz;
  92. block_sz = memory_block_size_bytes();
  93. /* Validate blk_sz is a power of 2 and not less than section size */
  94. if ((block_sz & (block_sz - 1)) || (block_sz < MIN_MEMORY_BLOCK_SIZE)) {
  95. WARN_ON(1);
  96. block_sz = MIN_MEMORY_BLOCK_SIZE;
  97. }
  98. return block_sz;
  99. }
  100. /*
  101. * use this as the physical section index that this memsection
  102. * uses.
  103. */
  104. static ssize_t show_mem_start_phys_index(struct device *dev,
  105. struct device_attribute *attr, char *buf)
  106. {
  107. struct memory_block *mem =
  108. container_of(dev, struct memory_block, dev);
  109. unsigned long phys_index;
  110. phys_index = mem->start_section_nr / sections_per_block;
  111. return sprintf(buf, "%08lx\n", phys_index);
  112. }
  113. static ssize_t show_mem_end_phys_index(struct device *dev,
  114. struct device_attribute *attr, char *buf)
  115. {
  116. struct memory_block *mem =
  117. container_of(dev, struct memory_block, dev);
  118. unsigned long phys_index;
  119. phys_index = mem->end_section_nr / sections_per_block;
  120. return sprintf(buf, "%08lx\n", phys_index);
  121. }
  122. /*
  123. * Show whether the section of memory is likely to be hot-removable
  124. */
  125. static ssize_t show_mem_removable(struct device *dev,
  126. struct device_attribute *attr, char *buf)
  127. {
  128. unsigned long i, pfn;
  129. int ret = 1;
  130. struct memory_block *mem =
  131. container_of(dev, struct memory_block, dev);
  132. for (i = 0; i < sections_per_block; i++) {
  133. pfn = section_nr_to_pfn(mem->start_section_nr + i);
  134. ret &= is_mem_section_removable(pfn, PAGES_PER_SECTION);
  135. }
  136. return sprintf(buf, "%d\n", ret);
  137. }
  138. /*
  139. * online, offline, going offline, etc.
  140. */
  141. static ssize_t show_mem_state(struct device *dev,
  142. struct device_attribute *attr, char *buf)
  143. {
  144. struct memory_block *mem =
  145. container_of(dev, struct memory_block, dev);
  146. ssize_t len = 0;
  147. /*
  148. * We can probably put these states in a nice little array
  149. * so that they're not open-coded
  150. */
  151. switch (mem->state) {
  152. case MEM_ONLINE:
  153. len = sprintf(buf, "online\n");
  154. break;
  155. case MEM_OFFLINE:
  156. len = sprintf(buf, "offline\n");
  157. break;
  158. case MEM_GOING_OFFLINE:
  159. len = sprintf(buf, "going-offline\n");
  160. break;
  161. default:
  162. len = sprintf(buf, "ERROR-UNKNOWN-%ld\n",
  163. mem->state);
  164. WARN_ON(1);
  165. break;
  166. }
  167. return len;
  168. }
  169. int memory_notify(unsigned long val, void *v)
  170. {
  171. return blocking_notifier_call_chain(&memory_chain, val, v);
  172. }
  173. int memory_isolate_notify(unsigned long val, void *v)
  174. {
  175. return atomic_notifier_call_chain(&memory_isolate_chain, val, v);
  176. }
  177. /*
  178. * The probe routines leave the pages reserved, just as the bootmem code does.
  179. * Make sure they're still that way.
  180. */
  181. static bool pages_correctly_reserved(unsigned long start_pfn,
  182. unsigned long nr_pages)
  183. {
  184. int i, j;
  185. struct page *page;
  186. unsigned long pfn = start_pfn;
  187. /*
  188. * memmap between sections is not contiguous except with
  189. * SPARSEMEM_VMEMMAP. We lookup the page once per section
  190. * and assume memmap is contiguous within each section
  191. */
  192. for (i = 0; i < sections_per_block; i++, pfn += PAGES_PER_SECTION) {
  193. if (WARN_ON_ONCE(!pfn_valid(pfn)))
  194. return false;
  195. page = pfn_to_page(pfn);
  196. for (j = 0; j < PAGES_PER_SECTION; j++) {
  197. if (PageReserved(page + j))
  198. continue;
  199. printk(KERN_WARNING "section number %ld page number %d "
  200. "not reserved, was it already online?\n",
  201. pfn_to_section_nr(pfn), j);
  202. return false;
  203. }
  204. }
  205. return true;
  206. }
  207. /*
  208. * MEMORY_HOTPLUG depends on SPARSEMEM in mm/Kconfig, so it is
  209. * OK to have direct references to sparsemem variables in here.
  210. */
  211. static int
  212. memory_block_action(unsigned long phys_index, unsigned long action, int online_type)
  213. {
  214. unsigned long start_pfn;
  215. unsigned long nr_pages = PAGES_PER_SECTION * sections_per_block;
  216. struct page *first_page;
  217. int ret;
  218. first_page = pfn_to_page(phys_index << PFN_SECTION_SHIFT);
  219. start_pfn = page_to_pfn(first_page);
  220. switch (action) {
  221. case MEM_ONLINE:
  222. if (!pages_correctly_reserved(start_pfn, nr_pages))
  223. return -EBUSY;
  224. ret = online_pages(start_pfn, nr_pages, online_type);
  225. break;
  226. case MEM_OFFLINE:
  227. ret = offline_pages(start_pfn, nr_pages);
  228. break;
  229. default:
  230. WARN(1, KERN_WARNING "%s(%ld, %ld) unknown action: "
  231. "%ld\n", __func__, phys_index, action, action);
  232. ret = -EINVAL;
  233. }
  234. return ret;
  235. }
  236. static int __memory_block_change_state(struct memory_block *mem,
  237. unsigned long to_state, unsigned long from_state_req,
  238. int online_type)
  239. {
  240. int ret = 0;
  241. if (mem->state != from_state_req) {
  242. ret = -EINVAL;
  243. goto out;
  244. }
  245. if (to_state == MEM_OFFLINE)
  246. mem->state = MEM_GOING_OFFLINE;
  247. ret = memory_block_action(mem->start_section_nr, to_state, online_type);
  248. if (ret) {
  249. mem->state = from_state_req;
  250. goto out;
  251. }
  252. mem->state = to_state;
  253. switch (mem->state) {
  254. case MEM_OFFLINE:
  255. kobject_uevent(&mem->dev.kobj, KOBJ_OFFLINE);
  256. break;
  257. case MEM_ONLINE:
  258. kobject_uevent(&mem->dev.kobj, KOBJ_ONLINE);
  259. break;
  260. default:
  261. break;
  262. }
  263. out:
  264. return ret;
  265. }
  266. static int memory_block_change_state(struct memory_block *mem,
  267. unsigned long to_state, unsigned long from_state_req,
  268. int online_type)
  269. {
  270. int ret;
  271. mutex_lock(&mem->state_mutex);
  272. ret = __memory_block_change_state(mem, to_state, from_state_req,
  273. online_type);
  274. mutex_unlock(&mem->state_mutex);
  275. return ret;
  276. }
  277. static ssize_t
  278. store_mem_state(struct device *dev,
  279. struct device_attribute *attr, const char *buf, size_t count)
  280. {
  281. struct memory_block *mem;
  282. int ret = -EINVAL;
  283. mem = container_of(dev, struct memory_block, dev);
  284. if (!strncmp(buf, "online_kernel", min_t(int, count, 13)))
  285. ret = memory_block_change_state(mem, MEM_ONLINE,
  286. MEM_OFFLINE, ONLINE_KERNEL);
  287. else if (!strncmp(buf, "online_movable", min_t(int, count, 14)))
  288. ret = memory_block_change_state(mem, MEM_ONLINE,
  289. MEM_OFFLINE, ONLINE_MOVABLE);
  290. else if (!strncmp(buf, "online", min_t(int, count, 6)))
  291. ret = memory_block_change_state(mem, MEM_ONLINE,
  292. MEM_OFFLINE, ONLINE_KEEP);
  293. else if(!strncmp(buf, "offline", min_t(int, count, 7)))
  294. ret = memory_block_change_state(mem, MEM_OFFLINE,
  295. MEM_ONLINE, -1);
  296. if (ret)
  297. return ret;
  298. return count;
  299. }
  300. /*
  301. * phys_device is a bad name for this. What I really want
  302. * is a way to differentiate between memory ranges that
  303. * are part of physical devices that constitute
  304. * a complete removable unit or fru.
  305. * i.e. do these ranges belong to the same physical device,
  306. * s.t. if I offline all of these sections I can then
  307. * remove the physical device?
  308. */
  309. static ssize_t show_phys_device(struct device *dev,
  310. struct device_attribute *attr, char *buf)
  311. {
  312. struct memory_block *mem =
  313. container_of(dev, struct memory_block, dev);
  314. return sprintf(buf, "%d\n", mem->phys_device);
  315. }
  316. static DEVICE_ATTR(phys_index, 0444, show_mem_start_phys_index, NULL);
  317. static DEVICE_ATTR(end_phys_index, 0444, show_mem_end_phys_index, NULL);
  318. static DEVICE_ATTR(state, 0644, show_mem_state, store_mem_state);
  319. static DEVICE_ATTR(phys_device, 0444, show_phys_device, NULL);
  320. static DEVICE_ATTR(removable, 0444, show_mem_removable, NULL);
  321. #define mem_create_simple_file(mem, attr_name) \
  322. device_create_file(&mem->dev, &dev_attr_##attr_name)
  323. #define mem_remove_simple_file(mem, attr_name) \
  324. device_remove_file(&mem->dev, &dev_attr_##attr_name)
  325. /*
  326. * Block size attribute stuff
  327. */
  328. static ssize_t
  329. print_block_size(struct device *dev, struct device_attribute *attr,
  330. char *buf)
  331. {
  332. return sprintf(buf, "%lx\n", get_memory_block_size());
  333. }
  334. static DEVICE_ATTR(block_size_bytes, 0444, print_block_size, NULL);
  335. static int block_size_init(void)
  336. {
  337. return device_create_file(memory_subsys.dev_root,
  338. &dev_attr_block_size_bytes);
  339. }
  340. /*
  341. * Some architectures will have custom drivers to do this, and
  342. * will not need to do it from userspace. The fake hot-add code
  343. * as well as ppc64 will do all of their discovery in userspace
  344. * and will require this interface.
  345. */
  346. #ifdef CONFIG_ARCH_MEMORY_PROBE
  347. static ssize_t
  348. memory_probe_store(struct device *dev, struct device_attribute *attr,
  349. const char *buf, size_t count)
  350. {
  351. u64 phys_addr;
  352. int nid;
  353. int i, ret;
  354. unsigned long pages_per_block = PAGES_PER_SECTION * sections_per_block;
  355. phys_addr = simple_strtoull(buf, NULL, 0);
  356. if (phys_addr & ((pages_per_block << PAGE_SHIFT) - 1))
  357. return -EINVAL;
  358. for (i = 0; i < sections_per_block; i++) {
  359. nid = memory_add_physaddr_to_nid(phys_addr);
  360. ret = add_memory(nid, phys_addr,
  361. PAGES_PER_SECTION << PAGE_SHIFT);
  362. if (ret)
  363. goto out;
  364. phys_addr += MIN_MEMORY_BLOCK_SIZE;
  365. }
  366. ret = count;
  367. out:
  368. return ret;
  369. }
  370. static DEVICE_ATTR(probe, S_IWUSR, NULL, memory_probe_store);
  371. static int memory_probe_init(void)
  372. {
  373. return device_create_file(memory_subsys.dev_root, &dev_attr_probe);
  374. }
  375. #else
  376. static inline int memory_probe_init(void)
  377. {
  378. return 0;
  379. }
  380. #endif
  381. #ifdef CONFIG_MEMORY_FAILURE
  382. /*
  383. * Support for offlining pages of memory
  384. */
  385. /* Soft offline a page */
  386. static ssize_t
  387. store_soft_offline_page(struct device *dev,
  388. struct device_attribute *attr,
  389. const char *buf, size_t count)
  390. {
  391. int ret;
  392. u64 pfn;
  393. if (!capable(CAP_SYS_ADMIN))
  394. return -EPERM;
  395. if (strict_strtoull(buf, 0, &pfn) < 0)
  396. return -EINVAL;
  397. pfn >>= PAGE_SHIFT;
  398. if (!pfn_valid(pfn))
  399. return -ENXIO;
  400. ret = soft_offline_page(pfn_to_page(pfn), 0);
  401. return ret == 0 ? count : ret;
  402. }
  403. /* Forcibly offline a page, including killing processes. */
  404. static ssize_t
  405. store_hard_offline_page(struct device *dev,
  406. struct device_attribute *attr,
  407. const char *buf, size_t count)
  408. {
  409. int ret;
  410. u64 pfn;
  411. if (!capable(CAP_SYS_ADMIN))
  412. return -EPERM;
  413. if (strict_strtoull(buf, 0, &pfn) < 0)
  414. return -EINVAL;
  415. pfn >>= PAGE_SHIFT;
  416. ret = memory_failure(pfn, 0, 0);
  417. return ret ? ret : count;
  418. }
  419. static DEVICE_ATTR(soft_offline_page, S_IWUSR, NULL, store_soft_offline_page);
  420. static DEVICE_ATTR(hard_offline_page, S_IWUSR, NULL, store_hard_offline_page);
  421. static __init int memory_fail_init(void)
  422. {
  423. int err;
  424. err = device_create_file(memory_subsys.dev_root,
  425. &dev_attr_soft_offline_page);
  426. if (!err)
  427. err = device_create_file(memory_subsys.dev_root,
  428. &dev_attr_hard_offline_page);
  429. return err;
  430. }
  431. #else
  432. static inline int memory_fail_init(void)
  433. {
  434. return 0;
  435. }
  436. #endif
  437. /*
  438. * Note that phys_device is optional. It is here to allow for
  439. * differentiation between which *physical* devices each
  440. * section belongs to...
  441. */
  442. int __weak arch_get_memory_phys_device(unsigned long start_pfn)
  443. {
  444. return 0;
  445. }
  446. /*
  447. * A reference for the returned object is held and the reference for the
  448. * hinted object is released.
  449. */
  450. struct memory_block *find_memory_block_hinted(struct mem_section *section,
  451. struct memory_block *hint)
  452. {
  453. int block_id = base_memory_block_id(__section_nr(section));
  454. struct device *hintdev = hint ? &hint->dev : NULL;
  455. struct device *dev;
  456. dev = subsys_find_device_by_id(&memory_subsys, block_id, hintdev);
  457. if (hint)
  458. put_device(&hint->dev);
  459. if (!dev)
  460. return NULL;
  461. return container_of(dev, struct memory_block, dev);
  462. }
  463. /*
  464. * For now, we have a linear search to go find the appropriate
  465. * memory_block corresponding to a particular phys_index. If
  466. * this gets to be a real problem, we can always use a radix
  467. * tree or something here.
  468. *
  469. * This could be made generic for all device subsystems.
  470. */
  471. struct memory_block *find_memory_block(struct mem_section *section)
  472. {
  473. return find_memory_block_hinted(section, NULL);
  474. }
  475. static int init_memory_block(struct memory_block **memory,
  476. struct mem_section *section, unsigned long state)
  477. {
  478. struct memory_block *mem;
  479. unsigned long start_pfn;
  480. int scn_nr;
  481. int ret = 0;
  482. mem = kzalloc(sizeof(*mem), GFP_KERNEL);
  483. if (!mem)
  484. return -ENOMEM;
  485. scn_nr = __section_nr(section);
  486. mem->start_section_nr =
  487. base_memory_block_id(scn_nr) * sections_per_block;
  488. mem->end_section_nr = mem->start_section_nr + sections_per_block - 1;
  489. mem->state = state;
  490. mem->section_count++;
  491. mutex_init(&mem->state_mutex);
  492. start_pfn = section_nr_to_pfn(mem->start_section_nr);
  493. mem->phys_device = arch_get_memory_phys_device(start_pfn);
  494. ret = register_memory(mem);
  495. if (!ret)
  496. ret = mem_create_simple_file(mem, phys_index);
  497. if (!ret)
  498. ret = mem_create_simple_file(mem, end_phys_index);
  499. if (!ret)
  500. ret = mem_create_simple_file(mem, state);
  501. if (!ret)
  502. ret = mem_create_simple_file(mem, phys_device);
  503. if (!ret)
  504. ret = mem_create_simple_file(mem, removable);
  505. *memory = mem;
  506. return ret;
  507. }
  508. static int add_memory_section(int nid, struct mem_section *section,
  509. struct memory_block **mem_p,
  510. unsigned long state, enum mem_add_context context)
  511. {
  512. struct memory_block *mem = NULL;
  513. int scn_nr = __section_nr(section);
  514. int ret = 0;
  515. mutex_lock(&mem_sysfs_mutex);
  516. if (context == BOOT) {
  517. /* same memory block ? */
  518. if (mem_p && *mem_p)
  519. if (scn_nr >= (*mem_p)->start_section_nr &&
  520. scn_nr <= (*mem_p)->end_section_nr) {
  521. mem = *mem_p;
  522. kobject_get(&mem->dev.kobj);
  523. }
  524. } else
  525. mem = find_memory_block(section);
  526. if (mem) {
  527. mem->section_count++;
  528. kobject_put(&mem->dev.kobj);
  529. } else {
  530. ret = init_memory_block(&mem, section, state);
  531. /* store memory_block pointer for next loop */
  532. if (!ret && context == BOOT)
  533. if (mem_p)
  534. *mem_p = mem;
  535. }
  536. if (!ret) {
  537. if (context == HOTPLUG &&
  538. mem->section_count == sections_per_block)
  539. ret = register_mem_sect_under_node(mem, nid);
  540. }
  541. mutex_unlock(&mem_sysfs_mutex);
  542. return ret;
  543. }
  544. int remove_memory_block(unsigned long node_id, struct mem_section *section,
  545. int phys_device)
  546. {
  547. struct memory_block *mem;
  548. mutex_lock(&mem_sysfs_mutex);
  549. mem = find_memory_block(section);
  550. unregister_mem_sect_under_nodes(mem, __section_nr(section));
  551. mem->section_count--;
  552. if (mem->section_count == 0) {
  553. mem_remove_simple_file(mem, phys_index);
  554. mem_remove_simple_file(mem, end_phys_index);
  555. mem_remove_simple_file(mem, state);
  556. mem_remove_simple_file(mem, phys_device);
  557. mem_remove_simple_file(mem, removable);
  558. unregister_memory(mem);
  559. } else
  560. kobject_put(&mem->dev.kobj);
  561. mutex_unlock(&mem_sysfs_mutex);
  562. return 0;
  563. }
  564. /*
  565. * need an interface for the VM to add new memory regions,
  566. * but without onlining it.
  567. */
  568. int register_new_memory(int nid, struct mem_section *section)
  569. {
  570. return add_memory_section(nid, section, NULL, MEM_OFFLINE, HOTPLUG);
  571. }
  572. int unregister_memory_section(struct mem_section *section)
  573. {
  574. if (!present_section(section))
  575. return -EINVAL;
  576. return remove_memory_block(0, section, 0);
  577. }
  578. /*
  579. * offline one memory block. If the memory block has been offlined, do nothing.
  580. */
  581. int offline_memory_block(struct memory_block *mem)
  582. {
  583. int ret = 0;
  584. mutex_lock(&mem->state_mutex);
  585. if (mem->state != MEM_OFFLINE)
  586. ret = __memory_block_change_state(mem, MEM_OFFLINE, MEM_ONLINE, -1);
  587. mutex_unlock(&mem->state_mutex);
  588. return ret;
  589. }
  590. /* return true if the memory block is offlined, otherwise, return false */
  591. bool is_memblock_offlined(struct memory_block *mem)
  592. {
  593. return mem->state == MEM_OFFLINE;
  594. }
  595. /*
  596. * Initialize the sysfs support for memory devices...
  597. */
  598. int __init memory_dev_init(void)
  599. {
  600. unsigned int i;
  601. int ret;
  602. int err;
  603. unsigned long block_sz;
  604. struct memory_block *mem = NULL;
  605. ret = subsys_system_register(&memory_subsys, NULL);
  606. if (ret)
  607. goto out;
  608. block_sz = get_memory_block_size();
  609. sections_per_block = block_sz / MIN_MEMORY_BLOCK_SIZE;
  610. /*
  611. * Create entries for memory sections that were found
  612. * during boot and have been initialized
  613. */
  614. for (i = 0; i < NR_MEM_SECTIONS; i++) {
  615. if (!present_section_nr(i))
  616. continue;
  617. /* don't need to reuse memory_block if only one per block */
  618. err = add_memory_section(0, __nr_to_section(i),
  619. (sections_per_block == 1) ? NULL : &mem,
  620. MEM_ONLINE,
  621. BOOT);
  622. if (!ret)
  623. ret = err;
  624. }
  625. err = memory_probe_init();
  626. if (!ret)
  627. ret = err;
  628. err = memory_fail_init();
  629. if (!ret)
  630. ret = err;
  631. err = block_size_init();
  632. if (!ret)
  633. ret = err;
  634. out:
  635. if (ret)
  636. printk(KERN_ERR "%s() failed: %d\n", __func__, ret);
  637. return ret;
  638. }