提交 b61bfa3c 编写于 作者: J Johannes Weiner 提交者: Linus Torvalds

mm: move bootmem descriptors definition to a single place

There are a lot of places that define either a single bootmem descriptor or an
array of them.  Use only one central array with MAX_NUMNODES items instead.
Signed-off-by: NJohannes Weiner <hannes@saeurebad.de>
Acked-by: NRalf Baechle <ralf@linux-mips.org>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Richard Henderson <rth@twiddle.net>
Cc: Russell King <rmk@arm.linux.org.uk>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Hirokazu Takata <takata@linux-m32r.org>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: Kyle McMartin <kyle@parisc-linux.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Paul Mundt <lethal@linux-sh.org>
Cc: David S. Miller <davem@davemloft.net>
Cc: Yinghai Lu <yhlu.kernel@gmail.com>
Cc: Christoph Lameter <cl@linux-foundation.org>
Cc: Mel Gorman <mel@csn.ul.ie>
Cc: Andy Whitcroft <apw@shadowen.org>
Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
上级 8b05c7e6
...@@ -19,7 +19,6 @@ ...@@ -19,7 +19,6 @@
#include <asm/pgalloc.h> #include <asm/pgalloc.h>
pg_data_t node_data[MAX_NUMNODES]; pg_data_t node_data[MAX_NUMNODES];
bootmem_data_t node_bdata[MAX_NUMNODES];
EXPORT_SYMBOL(node_data); EXPORT_SYMBOL(node_data);
#undef DEBUG_DISCONTIG #undef DEBUG_DISCONTIG
...@@ -141,7 +140,7 @@ setup_memory_node(int nid, void *kernel_end) ...@@ -141,7 +140,7 @@ setup_memory_node(int nid, void *kernel_end)
printk(" not enough mem to reserve NODE_DATA"); printk(" not enough mem to reserve NODE_DATA");
return; return;
} }
NODE_DATA(nid)->bdata = &node_bdata[nid]; NODE_DATA(nid)->bdata = &bootmem_node_data[nid];
printk(" Detected node memory: start %8lu, end %8lu\n", printk(" Detected node memory: start %8lu, end %8lu\n",
node_min_pfn, node_max_pfn); node_min_pfn, node_max_pfn);
...@@ -304,8 +303,9 @@ void __init paging_init(void) ...@@ -304,8 +303,9 @@ void __init paging_init(void)
dma_local_pfn = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT; dma_local_pfn = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
for_each_online_node(nid) { for_each_online_node(nid) {
unsigned long start_pfn = node_bdata[nid].node_boot_start >> PAGE_SHIFT; bootmem_data_t *bdata = &bootmem_node_data[nid];
unsigned long end_pfn = node_bdata[nid].node_low_pfn; unsigned long start_pfn = bdata->node_boot_start >> PAGE_SHIFT;
unsigned long end_pfn = bdata->node_low_pfn;
if (dma_local_pfn >= end_pfn - start_pfn) if (dma_local_pfn >= end_pfn - start_pfn)
zones_size[ZONE_DMA] = end_pfn - start_pfn; zones_size[ZONE_DMA] = end_pfn - start_pfn;
......
...@@ -21,26 +21,24 @@ ...@@ -21,26 +21,24 @@
* Our node_data structure for discontiguous memory. * Our node_data structure for discontiguous memory.
*/ */
static bootmem_data_t node_bootmem_data[MAX_NUMNODES];
pg_data_t discontig_node_data[MAX_NUMNODES] = { pg_data_t discontig_node_data[MAX_NUMNODES] = {
{ .bdata = &node_bootmem_data[0] }, { .bdata = &bootmem_node_data[0] },
{ .bdata = &node_bootmem_data[1] }, { .bdata = &bootmem_node_data[1] },
{ .bdata = &node_bootmem_data[2] }, { .bdata = &bootmem_node_data[2] },
{ .bdata = &node_bootmem_data[3] }, { .bdata = &bootmem_node_data[3] },
#if MAX_NUMNODES == 16 #if MAX_NUMNODES == 16
{ .bdata = &node_bootmem_data[4] }, { .bdata = &bootmem_node_data[4] },
{ .bdata = &node_bootmem_data[5] }, { .bdata = &bootmem_node_data[5] },
{ .bdata = &node_bootmem_data[6] }, { .bdata = &bootmem_node_data[6] },
{ .bdata = &node_bootmem_data[7] }, { .bdata = &bootmem_node_data[7] },
{ .bdata = &node_bootmem_data[8] }, { .bdata = &bootmem_node_data[8] },
{ .bdata = &node_bootmem_data[9] }, { .bdata = &bootmem_node_data[9] },
{ .bdata = &node_bootmem_data[10] }, { .bdata = &bootmem_node_data[10] },
{ .bdata = &node_bootmem_data[11] }, { .bdata = &bootmem_node_data[11] },
{ .bdata = &node_bootmem_data[12] }, { .bdata = &bootmem_node_data[12] },
{ .bdata = &node_bootmem_data[13] }, { .bdata = &bootmem_node_data[13] },
{ .bdata = &node_bootmem_data[14] }, { .bdata = &bootmem_node_data[14] },
{ .bdata = &node_bootmem_data[15] }, { .bdata = &bootmem_node_data[15] },
#endif #endif
}; };
......
...@@ -36,7 +36,6 @@ struct early_node_data { ...@@ -36,7 +36,6 @@ struct early_node_data {
struct ia64_node_data *node_data; struct ia64_node_data *node_data;
unsigned long pernode_addr; unsigned long pernode_addr;
unsigned long pernode_size; unsigned long pernode_size;
struct bootmem_data bootmem_data;
unsigned long num_physpages; unsigned long num_physpages;
#ifdef CONFIG_ZONE_DMA #ifdef CONFIG_ZONE_DMA
unsigned long num_dma_physpages; unsigned long num_dma_physpages;
...@@ -76,7 +75,7 @@ static int __init build_node_maps(unsigned long start, unsigned long len, ...@@ -76,7 +75,7 @@ static int __init build_node_maps(unsigned long start, unsigned long len,
int node) int node)
{ {
unsigned long cstart, epfn, end = start + len; unsigned long cstart, epfn, end = start + len;
struct bootmem_data *bdp = &mem_data[node].bootmem_data; struct bootmem_data *bdp = &bootmem_node_data[node];
epfn = GRANULEROUNDUP(end) >> PAGE_SHIFT; epfn = GRANULEROUNDUP(end) >> PAGE_SHIFT;
cstart = GRANULEROUNDDOWN(start); cstart = GRANULEROUNDDOWN(start);
...@@ -167,7 +166,7 @@ static void __init fill_pernode(int node, unsigned long pernode, ...@@ -167,7 +166,7 @@ static void __init fill_pernode(int node, unsigned long pernode,
{ {
void *cpu_data; void *cpu_data;
int cpus = early_nr_cpus_node(node); int cpus = early_nr_cpus_node(node);
struct bootmem_data *bdp = &mem_data[node].bootmem_data; struct bootmem_data *bdp = &bootmem_node_data[node];
mem_data[node].pernode_addr = pernode; mem_data[node].pernode_addr = pernode;
mem_data[node].pernode_size = pernodesize; mem_data[node].pernode_size = pernodesize;
...@@ -224,7 +223,7 @@ static int __init find_pernode_space(unsigned long start, unsigned long len, ...@@ -224,7 +223,7 @@ static int __init find_pernode_space(unsigned long start, unsigned long len,
{ {
unsigned long epfn; unsigned long epfn;
unsigned long pernodesize = 0, pernode, pages, mapsize; unsigned long pernodesize = 0, pernode, pages, mapsize;
struct bootmem_data *bdp = &mem_data[node].bootmem_data; struct bootmem_data *bdp = &bootmem_node_data[node];
epfn = (start + len) >> PAGE_SHIFT; epfn = (start + len) >> PAGE_SHIFT;
...@@ -440,7 +439,7 @@ void __init find_memory(void) ...@@ -440,7 +439,7 @@ void __init find_memory(void)
efi_memmap_walk(find_max_min_low_pfn, NULL); efi_memmap_walk(find_max_min_low_pfn, NULL);
for_each_online_node(node) for_each_online_node(node)
if (mem_data[node].bootmem_data.node_low_pfn) { if (bootmem_node_data[node].node_low_pfn) {
node_clear(node, memory_less_mask); node_clear(node, memory_less_mask);
mem_data[node].min_pfn = ~0UL; mem_data[node].min_pfn = ~0UL;
} }
...@@ -460,7 +459,7 @@ void __init find_memory(void) ...@@ -460,7 +459,7 @@ void __init find_memory(void)
else if (node_isset(node, memory_less_mask)) else if (node_isset(node, memory_less_mask))
continue; continue;
bdp = &mem_data[node].bootmem_data; bdp = &bootmem_node_data[node];
pernode = mem_data[node].pernode_addr; pernode = mem_data[node].pernode_addr;
pernodesize = mem_data[node].pernode_size; pernodesize = mem_data[node].pernode_size;
map = pernode + pernodesize; map = pernode + pernodesize;
......
...@@ -20,7 +20,6 @@ extern char _end[]; ...@@ -20,7 +20,6 @@ extern char _end[];
struct pglist_data *node_data[MAX_NUMNODES]; struct pglist_data *node_data[MAX_NUMNODES];
EXPORT_SYMBOL(node_data); EXPORT_SYMBOL(node_data);
static bootmem_data_t node_bdata[MAX_NUMNODES] __initdata;
pg_data_t m32r_node_data[MAX_NUMNODES]; pg_data_t m32r_node_data[MAX_NUMNODES];
...@@ -81,7 +80,7 @@ unsigned long __init setup_memory(void) ...@@ -81,7 +80,7 @@ unsigned long __init setup_memory(void)
for_each_online_node(nid) { for_each_online_node(nid) {
mp = &mem_prof[nid]; mp = &mem_prof[nid];
NODE_DATA(nid)=(pg_data_t *)&m32r_node_data[nid]; NODE_DATA(nid)=(pg_data_t *)&m32r_node_data[nid];
NODE_DATA(nid)->bdata = &node_bdata[nid]; NODE_DATA(nid)->bdata = &bootmem_node_data[nid];
min_pfn = mp->start_pfn; min_pfn = mp->start_pfn;
max_pfn = mp->start_pfn + mp->pages; max_pfn = mp->start_pfn + mp->pages;
bootmap_size = init_bootmem_node(NODE_DATA(nid), mp->free_pfn, bootmap_size = init_bootmem_node(NODE_DATA(nid), mp->free_pfn,
...@@ -163,4 +162,3 @@ unsigned long __init zone_sizes_init(void) ...@@ -163,4 +162,3 @@ unsigned long __init zone_sizes_init(void)
return holes; return holes;
} }
...@@ -32,8 +32,6 @@ ...@@ -32,8 +32,6 @@
DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
static bootmem_data_t __initdata bootmem_data[MAX_NUMNODES];
pg_data_t pg_data_map[MAX_NUMNODES]; pg_data_t pg_data_map[MAX_NUMNODES];
EXPORT_SYMBOL(pg_data_map); EXPORT_SYMBOL(pg_data_map);
...@@ -58,7 +56,7 @@ void __init m68k_setup_node(int node) ...@@ -58,7 +56,7 @@ void __init m68k_setup_node(int node)
pg_data_table[i] = pg_data_map + node; pg_data_table[i] = pg_data_map + node;
} }
#endif #endif
pg_data_map[node].bdata = bootmem_data + node; pg_data_map[node].bdata = bootmem_node_data + node;
node_set_online(node); node_set_online(node);
} }
......
...@@ -33,8 +33,6 @@ ...@@ -33,8 +33,6 @@
#define SLOT_PFNSHIFT (SLOT_SHIFT - PAGE_SHIFT) #define SLOT_PFNSHIFT (SLOT_SHIFT - PAGE_SHIFT)
#define PFN_NASIDSHFT (NASID_SHFT - PAGE_SHIFT) #define PFN_NASIDSHFT (NASID_SHFT - PAGE_SHIFT)
static struct bootmem_data __initdata plat_node_bdata[MAX_COMPACT_NODES];
struct node_data *__node_data[MAX_COMPACT_NODES]; struct node_data *__node_data[MAX_COMPACT_NODES];
EXPORT_SYMBOL(__node_data); EXPORT_SYMBOL(__node_data);
...@@ -403,7 +401,7 @@ static void __init node_mem_init(cnodeid_t node) ...@@ -403,7 +401,7 @@ static void __init node_mem_init(cnodeid_t node)
*/ */
__node_data[node] = __va(slot_freepfn << PAGE_SHIFT); __node_data[node] = __va(slot_freepfn << PAGE_SHIFT);
NODE_DATA(node)->bdata = &plat_node_bdata[node]; NODE_DATA(node)->bdata = &bootmem_node_data[node];
NODE_DATA(node)->node_start_pfn = start_pfn; NODE_DATA(node)->node_start_pfn = start_pfn;
NODE_DATA(node)->node_spanned_pages = end_pfn - start_pfn; NODE_DATA(node)->node_spanned_pages = end_pfn - start_pfn;
......
...@@ -36,7 +36,6 @@ extern int data_start; ...@@ -36,7 +36,6 @@ extern int data_start;
#ifdef CONFIG_DISCONTIGMEM #ifdef CONFIG_DISCONTIGMEM
struct node_map_data node_data[MAX_NUMNODES] __read_mostly; struct node_map_data node_data[MAX_NUMNODES] __read_mostly;
bootmem_data_t bmem_data[MAX_NUMNODES] __read_mostly;
unsigned char pfnnid_map[PFNNID_MAP_MAX] __read_mostly; unsigned char pfnnid_map[PFNNID_MAP_MAX] __read_mostly;
#endif #endif
...@@ -262,7 +261,7 @@ static void __init setup_bootmem(void) ...@@ -262,7 +261,7 @@ static void __init setup_bootmem(void)
#ifdef CONFIG_DISCONTIGMEM #ifdef CONFIG_DISCONTIGMEM
for (i = 0; i < MAX_PHYSMEM_RANGES; i++) { for (i = 0; i < MAX_PHYSMEM_RANGES; i++) {
memset(NODE_DATA(i), 0, sizeof(pg_data_t)); memset(NODE_DATA(i), 0, sizeof(pg_data_t));
NODE_DATA(i)->bdata = &bmem_data[i]; NODE_DATA(i)->bdata = &bootmem_node_data[i];
} }
memset(pfnnid_map, 0xff, sizeof(pfnnid_map)); memset(pfnnid_map, 0xff, sizeof(pfnnid_map));
......
...@@ -39,7 +39,6 @@ EXPORT_SYMBOL(numa_cpu_lookup_table); ...@@ -39,7 +39,6 @@ EXPORT_SYMBOL(numa_cpu_lookup_table);
EXPORT_SYMBOL(numa_cpumask_lookup_table); EXPORT_SYMBOL(numa_cpumask_lookup_table);
EXPORT_SYMBOL(node_data); EXPORT_SYMBOL(node_data);
static bootmem_data_t __initdata plat_node_bdata[MAX_NUMNODES];
static int min_common_depth; static int min_common_depth;
static int n_mem_addr_cells, n_mem_size_cells; static int n_mem_addr_cells, n_mem_size_cells;
...@@ -816,7 +815,7 @@ void __init do_init_bootmem(void) ...@@ -816,7 +815,7 @@ void __init do_init_bootmem(void)
dbg("node %d\n", nid); dbg("node %d\n", nid);
dbg("NODE_DATA() = %p\n", NODE_DATA(nid)); dbg("NODE_DATA() = %p\n", NODE_DATA(nid));
NODE_DATA(nid)->bdata = &plat_node_bdata[nid]; NODE_DATA(nid)->bdata = &bootmem_node_data[nid];
NODE_DATA(nid)->node_start_pfn = start_pfn; NODE_DATA(nid)->node_start_pfn = start_pfn;
NODE_DATA(nid)->node_spanned_pages = end_pfn - start_pfn; NODE_DATA(nid)->node_spanned_pages = end_pfn - start_pfn;
......
...@@ -14,7 +14,6 @@ ...@@ -14,7 +14,6 @@
#include <linux/pfn.h> #include <linux/pfn.h>
#include <asm/sections.h> #include <asm/sections.h>
static bootmem_data_t plat_node_bdata[MAX_NUMNODES];
struct pglist_data *node_data[MAX_NUMNODES] __read_mostly; struct pglist_data *node_data[MAX_NUMNODES] __read_mostly;
EXPORT_SYMBOL_GPL(node_data); EXPORT_SYMBOL_GPL(node_data);
...@@ -35,7 +34,7 @@ void __init setup_memory(void) ...@@ -35,7 +34,7 @@ void __init setup_memory(void)
NODE_DATA(0) = pfn_to_kaddr(free_pfn); NODE_DATA(0) = pfn_to_kaddr(free_pfn);
memset(NODE_DATA(0), 0, sizeof(struct pglist_data)); memset(NODE_DATA(0), 0, sizeof(struct pglist_data));
free_pfn += PFN_UP(sizeof(struct pglist_data)); free_pfn += PFN_UP(sizeof(struct pglist_data));
NODE_DATA(0)->bdata = &plat_node_bdata[0]; NODE_DATA(0)->bdata = &bootmem_node_data[0];
/* Set up node 0 */ /* Set up node 0 */
setup_bootmem_allocator(free_pfn); setup_bootmem_allocator(free_pfn);
...@@ -66,7 +65,7 @@ void __init setup_bootmem_node(int nid, unsigned long start, unsigned long end) ...@@ -66,7 +65,7 @@ void __init setup_bootmem_node(int nid, unsigned long start, unsigned long end)
free_pfn += PFN_UP(sizeof(struct pglist_data)); free_pfn += PFN_UP(sizeof(struct pglist_data));
memset(NODE_DATA(nid), 0, sizeof(struct pglist_data)); memset(NODE_DATA(nid), 0, sizeof(struct pglist_data));
NODE_DATA(nid)->bdata = &plat_node_bdata[nid]; NODE_DATA(nid)->bdata = &bootmem_node_data[nid];
NODE_DATA(nid)->node_start_pfn = start_pfn; NODE_DATA(nid)->node_start_pfn = start_pfn;
NODE_DATA(nid)->node_spanned_pages = end_pfn - start_pfn; NODE_DATA(nid)->node_spanned_pages = end_pfn - start_pfn;
......
...@@ -788,7 +788,6 @@ int numa_cpu_lookup_table[NR_CPUS]; ...@@ -788,7 +788,6 @@ int numa_cpu_lookup_table[NR_CPUS];
cpumask_t numa_cpumask_lookup_table[MAX_NUMNODES]; cpumask_t numa_cpumask_lookup_table[MAX_NUMNODES];
#ifdef CONFIG_NEED_MULTIPLE_NODES #ifdef CONFIG_NEED_MULTIPLE_NODES
static bootmem_data_t plat_node_bdata[MAX_NUMNODES];
struct mdesc_mblock { struct mdesc_mblock {
u64 base; u64 base;
...@@ -871,7 +870,7 @@ static void __init allocate_node_data(int nid) ...@@ -871,7 +870,7 @@ static void __init allocate_node_data(int nid)
NODE_DATA(nid) = __va(paddr); NODE_DATA(nid) = __va(paddr);
memset(NODE_DATA(nid), 0, sizeof(struct pglist_data)); memset(NODE_DATA(nid), 0, sizeof(struct pglist_data));
NODE_DATA(nid)->bdata = &plat_node_bdata[nid]; NODE_DATA(nid)->bdata = &bootmem_node_data[nid];
#endif #endif
p = NODE_DATA(nid); p = NODE_DATA(nid);
......
...@@ -42,7 +42,6 @@ ...@@ -42,7 +42,6 @@
struct pglist_data *node_data[MAX_NUMNODES] __read_mostly; struct pglist_data *node_data[MAX_NUMNODES] __read_mostly;
EXPORT_SYMBOL(node_data); EXPORT_SYMBOL(node_data);
static bootmem_data_t node0_bdata;
/* /*
* numa interface - we expect the numa architecture specific code to have * numa interface - we expect the numa architecture specific code to have
...@@ -385,7 +384,7 @@ void __init initmem_init(unsigned long start_pfn, ...@@ -385,7 +384,7 @@ void __init initmem_init(unsigned long start_pfn,
for_each_online_node(nid) for_each_online_node(nid)
memset(NODE_DATA(nid), 0, sizeof(struct pglist_data)); memset(NODE_DATA(nid), 0, sizeof(struct pglist_data));
NODE_DATA(0)->bdata = &node0_bdata; NODE_DATA(0)->bdata = &bootmem_node_data[0];
setup_bootmem_allocator(); setup_bootmem_allocator();
} }
......
...@@ -23,8 +23,6 @@ ...@@ -23,8 +23,6 @@
struct pglist_data *node_data[MAX_NUMNODES] __read_mostly; struct pglist_data *node_data[MAX_NUMNODES] __read_mostly;
EXPORT_SYMBOL(node_data); EXPORT_SYMBOL(node_data);
static bootmem_data_t plat_node_bdata[MAX_NUMNODES];
struct memnode memnode; struct memnode memnode;
s16 apicid_to_node[MAX_LOCAL_APIC] __cpuinitdata = { s16 apicid_to_node[MAX_LOCAL_APIC] __cpuinitdata = {
...@@ -198,7 +196,7 @@ void __init setup_node_bootmem(int nodeid, unsigned long start, ...@@ -198,7 +196,7 @@ void __init setup_node_bootmem(int nodeid, unsigned long start,
nodedata_phys + pgdat_size - 1); nodedata_phys + pgdat_size - 1);
memset(NODE_DATA(nodeid), 0, sizeof(pg_data_t)); memset(NODE_DATA(nodeid), 0, sizeof(pg_data_t));
NODE_DATA(nodeid)->bdata = &plat_node_bdata[nodeid]; NODE_DATA(nodeid)->bdata = &bootmem_node_data[nodeid];
NODE_DATA(nodeid)->node_start_pfn = start_pfn; NODE_DATA(nodeid)->node_start_pfn = start_pfn;
NODE_DATA(nodeid)->node_spanned_pages = last_pfn - start_pfn; NODE_DATA(nodeid)->node_spanned_pages = last_pfn - start_pfn;
......
...@@ -38,6 +38,8 @@ typedef struct bootmem_data { ...@@ -38,6 +38,8 @@ typedef struct bootmem_data {
struct list_head list; struct list_head list;
} bootmem_data_t; } bootmem_data_t;
extern bootmem_data_t bootmem_node_data[];
extern unsigned long bootmem_bootmap_pages(unsigned long); extern unsigned long bootmem_bootmap_pages(unsigned long);
extern unsigned long init_bootmem(unsigned long addr, unsigned long memend); extern unsigned long init_bootmem(unsigned long addr, unsigned long memend);
extern void free_bootmem(unsigned long addr, unsigned long size); extern void free_bootmem(unsigned long addr, unsigned long size);
......
...@@ -36,6 +36,8 @@ static LIST_HEAD(bdata_list); ...@@ -36,6 +36,8 @@ static LIST_HEAD(bdata_list);
unsigned long saved_max_pfn; unsigned long saved_max_pfn;
#endif #endif
bootmem_data_t bootmem_node_data[MAX_NUMNODES] __initdata;
/* return the number of _pages_ that will be allocated for the boot bitmap */ /* return the number of _pages_ that will be allocated for the boot bitmap */
unsigned long __init bootmem_bootmap_pages(unsigned long pages) unsigned long __init bootmem_bootmap_pages(unsigned long pages)
{ {
......
...@@ -4040,9 +4040,7 @@ void __init set_dma_reserve(unsigned long new_dma_reserve) ...@@ -4040,9 +4040,7 @@ void __init set_dma_reserve(unsigned long new_dma_reserve)
} }
#ifndef CONFIG_NEED_MULTIPLE_NODES #ifndef CONFIG_NEED_MULTIPLE_NODES
static bootmem_data_t contig_bootmem_data; struct pglist_data contig_page_data = { .bdata = &bootmem_node_data[0] };
struct pglist_data contig_page_data = { .bdata = &contig_bootmem_data };
EXPORT_SYMBOL(contig_page_data); EXPORT_SYMBOL(contig_page_data);
#endif #endif
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册