All of lore.kernel.org
 help / color / mirror / Atom feed
From: Yinghai Lu <yhlu.kernel@gmail.com>
To: Ingo Molnar <mingo@elte.hu>, Thomas Gleixner <tglx@linutronix.de>,
	"H. Peter Anvin" <hpa@zytor.com>,
	"Eric W. Biederman" <ebiederm@xmission.com>,
	Dhaval Giani <dhaval@linux.vnet.ibm.com>,
	Mike Travis <travis@sgi.com>,
	Andrew Morton <akpm@linux-foundation.org>
Cc: linux-kernel@vger.kernel.org, Yinghai Lu <yhlu.kernel@gmail.com>
Subject: [PATCH 05/42] add per_cpu_dyn_array support
Date: Fri,  8 Aug 2008 14:52:11 -0700	[thread overview]
Message-ID: <1218232368-31228-6-git-send-email-yhlu.kernel@gmail.com> (raw)
In-Reply-To: <1218232368-31228-5-git-send-email-yhlu.kernel@gmail.com>

could make array in per_cpu is allocated dynamically too

usage:
| /* in .h */
|struct kernel_stat {
|       struct cpu_usage_stat   cpustat;
|       unsigned int *irqs;
|};
|
| /* in .c */
|DEFINE_PER_CPU(struct kernel_stat, kstat);
|
|DEFINE_PER_CPU_DYN_ARRAY_ADDR(per_cpu__kstat_irqs, per_cpu__kstat.irqs, sizeof(unsigned int), nr_irqs, sizeof(unsigned long), NULL);

after setup_percpu()/per_cpu_alloc_dyn_array(), that dyn_array in per_cpu area is ready to use

Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
---
 arch/x86/kernel/setup_percpu.c    |    7 +++-
 include/asm-generic/vmlinux.lds.h |    6 +++
 include/linux/init.h              |   27 ++++++++++++++--
 init/main.c                       |   63 +++++++++++++++++++++++++++++++++++-
 4 files changed, 96 insertions(+), 7 deletions(-)

diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c
index 0e67f72..13ba7a8 100644
--- a/arch/x86/kernel/setup_percpu.c
+++ b/arch/x86/kernel/setup_percpu.c
@@ -140,7 +140,7 @@ static void __init setup_cpu_pda_map(void)
  */
 void __init setup_per_cpu_areas(void)
 {
-	ssize_t size = PERCPU_ENOUGH_ROOM;
+	ssize_t size, old_size;
 	char *ptr;
 	int cpu;
 
@@ -148,7 +148,8 @@ void __init setup_per_cpu_areas(void)
 	setup_cpu_pda_map();
 
 	/* Copy section for each CPU (we discard the original) */
-	size = PERCPU_ENOUGH_ROOM;
+	old_size = PERCPU_ENOUGH_ROOM;
+	size = old_size + per_cpu_dyn_array_size();
 	printk(KERN_INFO "PERCPU: Allocating %zd bytes of per cpu data\n",
 			  size);
 
@@ -176,6 +177,8 @@ void __init setup_per_cpu_areas(void)
 		per_cpu_offset(cpu) = ptr - __per_cpu_start;
 		memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start);
 
+		per_cpu_alloc_dyn_array(cpu, ptr + old_size);
+
 	}
 
 	printk(KERN_DEBUG "NR_CPUS: %d, nr_cpu_ids: %d, nr_node_ids %d\n",
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 1c3daac..e76244a 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -220,6 +220,12 @@
 		VMLINUX_SYMBOL(__dyn_array_start) = .;			\
 		*(.dyn_array.init)					\
 		VMLINUX_SYMBOL(__dyn_array_end) = .;			\
+	}								\
+	. = ALIGN((align));						\
+	.per_cpu_dyn_array.init : AT(ADDR(.per_cpu_dyn_array.init) - LOAD_OFFSET) {	\
+		VMLINUX_SYMBOL(__per_cpu_dyn_array_start) = .;		\
+		*(.per_cpu_dyn_array.init)				\
+		VMLINUX_SYMBOL(__per_cpu_dyn_array_end) = .;		\
 	}
 #define SECURITY_INIT							\
 	.security_initcall.init : AT(ADDR(.security_initcall.init) - LOAD_OFFSET) { \
diff --git a/include/linux/init.h b/include/linux/init.h
index c31cd94..9fbe61b 100644
--- a/include/linux/init.h
+++ b/include/linux/init.h
@@ -258,12 +258,13 @@ struct dyn_array {
 	void (*init_work)(void *);
 };
 extern struct dyn_array *__dyn_array_start[], *__dyn_array_end[];
+extern struct dyn_array *__per_cpu_dyn_array_start[], *__per_cpu_dyn_array_end[];
 
-#define DEFINE_DYN_ARRAY(nameX, sizeX, nrX, alignX, init_workX) \
+#define DEFINE_DYN_ARRAY_ADDR(nameX, addrX, sizeX, nrX, alignX, init_workX) \
 		static struct dyn_array __dyn_array_##nameX __initdata = \
-		{	.name = (void **)&nameX,\
+		{	.name = (void **)&(nameX),\
 			.size = sizeX,\
-			.nr   = &nrX,\
+			.nr   = &(nrX),\
 			.align = alignX,\
 			.init_work = init_workX,\
 		}; \
@@ -271,7 +272,27 @@ extern struct dyn_array *__dyn_array_start[], *__dyn_array_end[];
 		__attribute__((__section__(".dyn_array.init"))) = \
 			&__dyn_array_##nameX
 
+#define DEFINE_DYN_ARRAY(nameX, sizeX, nrX, alignX, init_workX) \
+	DEFINE_DYN_ARRAY_ADDR(nameX, nameX, sizeX, nrX, alignX, init_workX)
+
+#define DEFINE_PER_CPU_DYN_ARRAY_ADDR(nameX, addrX, sizeX, nrX, alignX, init_workX) \
+		static struct dyn_array __per_cpu_dyn_array_##nameX __initdata = \
+		{	.name = (void **)&(addrX),\
+			.size = sizeX,\
+			.nr   = &(nrX),\
+			.align = alignX,\
+			.init_work = init_workX,\
+		}; \
+		static struct dyn_array *__per_cpu_dyn_array_ptr_##nameX __used \
+		__attribute__((__section__(".per_cpu_dyn_array.init"))) = \
+			&__per_cpu_dyn_array_##nameX
+
+#define DEFINE_PER_CPU_DYN_ARRAY(nameX, sizeX, nrX, alignX, init_workX) \
+	DEFINE_PER_CPU_DYN_ARRAY_ADDR(nameX, nameX, nrX, alignX, init_workX)
+
 extern void pre_alloc_dyn_array(void);
+extern unsigned long per_cpu_dyn_array_size(void);
+extern void per_cpu_alloc_dyn_array(int cpu, char *ptr);
 #endif /* __ASSEMBLY__ */
 
 /**
diff --git a/init/main.c b/init/main.c
index a53f1cf..18478d3 100644
--- a/init/main.c
+++ b/init/main.c
@@ -394,17 +394,19 @@ EXPORT_SYMBOL(__per_cpu_offset);
 
 static void __init setup_per_cpu_areas(void)
 {
-	unsigned long size, i;
+	unsigned long size, i, old_size;
 	char *ptr;
 	unsigned long nr_possible_cpus = num_possible_cpus();
 
 	/* Copy section for each CPU (we discard the original) */
-	size = ALIGN(PERCPU_ENOUGH_ROOM, PAGE_SIZE);
+	old_size = PERCPU_ENOUGH_ROOM;
+	size = ALIGN(old_size + per_cpu_dyn_array_size(), PAGE_SIZE);
 	ptr = alloc_bootmem_pages(size * nr_possible_cpus);
 
 	for_each_possible_cpu(i) {
 		__per_cpu_offset[i] = ptr - __per_cpu_start;
 		memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start);
+		per_cpu_alloc_dyn_array(cpu, ptr + old_size);
 		ptr += size;
 	}
 }
@@ -562,6 +564,63 @@ void pre_alloc_dyn_array(void)
 #endif
 }
 
+unsigned long per_cpu_dyn_array_size(void)
+{
+	unsigned long total_size = 0;
+#ifdef CONFIG_HAVE_DYN_ARRAY
+	unsigned long size;
+	struct dyn_array **daa;
+
+	for (daa = __per_cpu_dyn_array_start ; daa < __per_cpu_dyn_array_end; daa++) {
+		struct dyn_array *da = *daa;
+
+		size = da->size * (*da->nr);
+		print_fn_descriptor_symbol("per_cpu_dyna_array %s ", da->name);
+		printk(KERN_CONT "size:%#lx nr:%d align:%#lx\n",
+			da->size, *da->nr, da->align);
+		total_size += roundup(size, da->align);
+	}
+	if (total_size)
+		printk(KERN_DEBUG "per_cpu_dyna_array total_size: %#lx\n",
+			 total_size);
+#endif
+	return total_size;
+}
+
+void per_cpu_alloc_dyn_array(int cpu, char *ptr)
+{
+#ifdef CONFIG_HAVE_DYN_ARRAY
+	unsigned long size, phys;
+	struct dyn_array **daa;
+	unsigned long addr;
+	void **array;
+
+	phys = virt_to_phys(ptr);
+
+	for (daa = __per_cpu_dyn_array_start ; daa < __per_cpu_dyn_array_end; daa++) {
+		struct dyn_array *da = *daa;
+
+		size = da->size * (*da->nr);
+		print_fn_descriptor_symbol("per_cpu_dyna_array %s ", da->name);
+		printk(KERN_CONT "size:%#lx nr:%d align:%#lx",
+			da->size, *da->nr, da->align);
+
+		phys = roundup(phys, da->align);
+		addr = (unsigned long)da->name;
+		addr += per_cpu_offset(cpu);
+		array = (void **)addr;
+		*array = phys_to_virt(phys);
+		*da->name = *array; /* so init_work could use it directly */
+		printk(KERN_CONT " %p ==> [%#lx - %#lx]\n", array, phys, phys + size);
+		phys += size;
+
+		if (da->init_work) {
+			da->init_work(da);
+		}
+	}
+#endif
+}
+
 asmlinkage void __init start_kernel(void)
 {
 	char * command_line;
-- 
1.5.4.5


  reply	other threads:[~2008-08-08 21:56 UTC|newest]

Thread overview: 66+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-08-08 21:52 [PATCH 00/42] dyn_array/nr_irqs/sparse_irq support v5 Yinghai Lu
2008-08-08 21:52 ` [PATCH 01/42] 8250: Remove NR_IRQ usage Yinghai Lu
2008-08-08 21:52   ` [PATCH 02/42] x86: add after_bootmem for 32bit Yinghai Lu
2008-08-08 21:52     ` [PATCH 03/42] x86: remove irq_vectors_limits Yinghai Lu
2008-08-08 21:52       ` [PATCH 04/42] add dyn_array support Yinghai Lu
2008-08-08 21:52         ` Yinghai Lu [this message]
2008-08-08 21:52           ` [PATCH 06/42] x86: alloc dyn_array all alltogether Yinghai Lu
2008-08-08 21:52             ` [PATCH 07/42] x86: enable dyn_array support Yinghai Lu
2008-08-08 21:52               ` [PATCH 08/42] introduce nr_irqs Yinghai Lu
2008-08-08 21:52                 ` [PATCH 09/42] x86: using nr_irqs Yinghai Lu
2008-08-08 21:52                   ` [PATCH 10/42] drivers/char to use nr_irqs Yinghai Lu
2008-08-08 21:52                     ` [PATCH 11/42] drivers/net " Yinghai Lu
2008-08-08 21:52                       ` [PATCH 12/42] drivers intr remapping " Yinghai Lu
2008-08-08 21:52                         ` [PATCH 13/42] drivers/pcmcia " Yinghai Lu
2008-08-08 21:52                           ` [PATCH 14/42] drivers/rtc " Yinghai Lu
2008-08-08 21:52                             ` [PATCH 15/42] drivers/scsi " Yinghai Lu
2008-08-08 21:52                               ` [PATCH 16/42] drivers/serial " Yinghai Lu
2008-08-08 21:52                                 ` [PATCH 17/42] drivers proc " Yinghai Lu
2008-08-08 21:52                                   ` [PATCH 18/42] drivers xen events " Yinghai Lu
2008-08-08 21:52                                     ` [PATCH 19/42] make irq_timer_state to use dyn_array Yinghai Lu
2008-08-08 21:52                                       ` [PATCH 20/42] make irq2_iommu " Yinghai Lu
2008-08-08 21:52                                         ` [PATCH 21/42] make irq_desc " Yinghai Lu
2008-08-08 21:52                                           ` [PATCH 22/42] irq: make irqs in kernel stat use per_cpu_dyn_array Yinghai Lu
2008-08-08 21:52                                             ` [PATCH 23/42] x86: use dyn_array in io_apic_xx.c Yinghai Lu
2008-08-08 21:52                                               ` [PATCH 24/42] x86: get mp_irqs from madt Yinghai Lu
2008-08-08 21:52                                                 ` [PATCH 25/42] x86: remove nr_irq_vectors Yinghai Lu
2008-08-08 21:52                                                   ` [PATCH 26/42] x86_64: use irq_desc() together with dyn_array Yinghai Lu
2008-08-08 21:52                                                     ` [PATCH 27/42] x86: add irq_cfg in io_apic_64.c Yinghai Lu
2008-08-08 21:52                                                       ` [PATCH 28/42] x86: put irq_2_pin pointer into irq_cfg Yinghai Lu
2008-08-08 21:52                                                         ` [PATCH 29/42] x86: put timer_rand_state pointer into irq_desc Yinghai Lu
2008-08-08 21:52                                                           ` [PATCH 30/42] x86: move kstat_irqs from kstat to irq_desc Yinghai Lu
2008-08-08 21:52                                                             ` [PATCH 31/42] replace loop with nr_irqs with for_each_irq_desc Yinghai Lu
2008-08-08 21:52                                                               ` [PATCH 32/42] replace loop with nr_irqs with for_each_irq_icfg Yinghai Lu
2008-08-08 21:52                                                                 ` [PATCH 33/42] remove >= nr_irqs checking with config_have_sparse_irq Yinghai Lu
2008-08-08 21:52                                                                   ` [PATCH 34/42] x86_64: add irq_desc in function in paramater Yinghai Lu
2008-08-08 21:52                                                                     ` [PATCH 35/42] x86: check with without_new in show_interrupts Yinghai Lu
2008-08-08 21:52                                                                       ` [PATCH 36/42] x86_64: introduce irq_cfg_with_new Yinghai Lu
2008-08-08 21:52                                                                         ` [PATCH 37/42] x86_64: introduce irq_desc_with_new Yinghai Lu
2008-08-08 21:52                                                                           ` [PATCH 38/42] seperate irq_descX with irq_descX_free Yinghai Lu
2008-08-08 21:52                                                                             ` [PATCH 39/42] x86_64: sperate irq_cfgx with irq_cfgx_free Yinghai Lu
2008-08-08 21:52                                                                               ` [PATCH 40/42] x86_64: make /proc/interrupts works with dyn irq_desc Yinghai Lu
2008-08-08 21:52                                                                                 ` [PATCH 41/42] x86_64: remove one nr_irqs in show_stat Yinghai Lu
2008-08-08 21:52                                                                                   ` [PATCH 42/42] x86: put irq_2_iommu pointer into irq_desc Yinghai Lu
2008-08-09  1:00                 ` [PATCH 08/42] introduce nr_irqs Eric W. Biederman
2008-08-09  1:38                   ` Yinghai Lu
2008-08-09  1:59                     ` H. Peter Anvin
2008-08-09  7:30                       ` Yinghai Lu
2008-08-09 16:02                         ` Eric W. Biederman
2008-08-09 21:21                           ` Yinghai Lu
2008-08-09 21:38                             ` Eric W. Biederman
2008-08-09 22:35                               ` Yinghai Lu
2008-08-09  6:07                     ` Eric W. Biederman
2008-08-09  7:30                       ` Yinghai Lu
2008-08-09 15:46                         ` Eric W. Biederman
2008-08-09 21:37                           ` Yinghai Lu
2008-08-08 22:38   ` [PATCH 01/42] 8250: Remove NR_IRQ usage Eric W. Biederman
2008-08-08 23:07     ` Yinghai Lu
2008-08-08 22:01 ` [PATCH 00/42] dyn_array/nr_irqs/sparse_irq support v5 H. Peter Anvin
2008-08-08 22:14   ` Yinghai Lu
2008-08-08 22:25     ` H. Peter Anvin
2008-08-08 22:30       ` Yinghai Lu
2008-08-08 22:33         ` H. Peter Anvin
2008-08-08 22:19 ` H. Peter Anvin
2008-08-08 22:26   ` Yinghai Lu
2008-08-08 23:40     ` Eric W. Biederman
2008-08-09  0:34   ` Yinghai Lu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1218232368-31228-6-git-send-email-yhlu.kernel@gmail.com \
    --to=yhlu.kernel@gmail.com \
    --cc=akpm@linux-foundation.org \
    --cc=dhaval@linux.vnet.ibm.com \
    --cc=ebiederm@xmission.com \
    --cc=hpa@zytor.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@elte.hu \
    --cc=tglx@linutronix.de \
    --cc=travis@sgi.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.