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