#include <boot_param.h>
 #include <loongson.h>
 
-static struct pglist_data prealloc__node_data[MAX_NUMNODES];
 unsigned char __node_distances[MAX_NUMNODES][MAX_NUMNODES];
 EXPORT_SYMBOL(__node_distances);
 struct pglist_data *__node_data[MAX_NUMNODES];
 
 static void __init node_mem_init(unsigned int node)
 {
+       struct pglist_data *nd;
        unsigned long node_addrspace_offset;
        unsigned long start_pfn, end_pfn;
+       unsigned long nd_pa;
+       int tnid;
+       const size_t nd_size = roundup(sizeof(pg_data_t), SMP_CACHE_BYTES);
 
        node_addrspace_offset = nid_to_addrbase(node);
        pr_info("Node%d's addrspace_offset is 0x%lx\n",
        pr_info("Node%d: start_pfn=0x%lx, end_pfn=0x%lx\n",
                node, start_pfn, end_pfn);
 
-       __node_data[node] = prealloc__node_data + node;
-
+       nd_pa = memblock_phys_alloc_try_nid(nd_size, SMP_CACHE_BYTES, node);
+       if (!nd_pa)
+               panic("Cannot allocate %zu bytes for node %d data\n",
+                     nd_size, node);
+       nd = __va(nd_pa);
+       memset(nd, 0, sizeof(struct pglist_data));
+       tnid = early_pfn_to_nid(nd_pa >> PAGE_SHIFT);
+       if (tnid != node)
+               pr_info("NODE_DATA(%d) on node %d\n", node, tnid);
+       __node_data[node] = nd;
        NODE_DATA(node)->node_start_pfn = start_pfn;
        NODE_DATA(node)->node_spanned_pages = end_pfn - start_pfn;