All of lore.kernel.org
 help / color / mirror / Atom feed
From: Tejun Heo <tj@kernel.org>
To: CAI Qian <caiqian@redhat.com>
Cc: graff yang <graff.yang@gmail.com>,
	Marcelo Tosatti <mtosatti@redhat.com>,
	kexec <kexec@lists.infradead.org>,
	linux-kernel <linux-kernel@vger.kernel.org>,
	dhowells@redhat.com, sonic adi <sonic.adi@gmail.com>,
	Chris Lalancette <clalance@redhat.com>,
	Avi Kivity <avi@redhat.com>
Subject: Re: kvm kdump regression
Date: Fri, 17 Sep 2010 17:22:07 +0200	[thread overview]
Message-ID: <4C93879F.6000201@kernel.org> (raw)
In-Reply-To: <391574593.869121284452994336.JavaMail.root@zmail06.collab.prod.int.phx2.redhat.com>

Hello,

Can you please apply the following patch, reproduce the problem and
report the kernel log?

Thanks.

diff --git a/arch/x86/kernel/crash_dump_64.c b/arch/x86/kernel/crash_dump_64.c
index 045b36c..8ac45a4 100644
--- a/arch/x86/kernel/crash_dump_64.c
+++ b/arch/x86/kernel/crash_dump_64.c
@@ -13,6 +13,7 @@
 /* Stores the physical address of elf header of crash image. */
 unsigned long long elfcorehdr_addr = ELFCORE_ADDR_MAX;

+void per_cpu_ptr_to_phys_failed(void *addr);
 /**
  * copy_oldmem_page - copy one page from "oldmem"
  * @pfn: page frame number to be copied
@@ -35,8 +36,10 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
 		return 0;

 	vaddr = ioremap(pfn << PAGE_SHIFT, PAGE_SIZE);
-	if (!vaddr)
+	if (!vaddr) {
+		per_cpu_ptr_to_phys_failed(vaddr);
 		return -ENOMEM;
+	}

 	if (userbuf) {
 		if (copy_to_user(buf, vaddr + offset, csize)) {
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 932eaee..3bbffb0 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -6540,6 +6540,8 @@ static void __init ata_parse_force_param(void)
 	ata_force_tbl_size = idx;
 }

+void per_cpu_ptr_to_phys_failed(void *addr);
+
 static int __init ata_init(void)
 {
 	int rc = -ENOMEM;
@@ -6553,6 +6555,7 @@ static int __init ata_init(void)
 	}

 	printk(KERN_DEBUG "libata version " DRV_VERSION " loaded.\n");
+	per_cpu_ptr_to_phys_failed(0x1234);
 	return 0;
 }

diff --git a/mm/percpu-vm.c b/mm/percpu-vm.c
index 7d9c1d0..357569a 100644
--- a/mm/percpu-vm.c
+++ b/mm/percpu-vm.c
@@ -415,6 +415,7 @@ static struct pcpu_chunk *pcpu_create_chunk(void)
 {
 	struct pcpu_chunk *chunk;
 	struct vm_struct **vms;
+	int i;

 	chunk = pcpu_alloc_chunk();
 	if (!chunk)
@@ -429,6 +430,13 @@ static struct pcpu_chunk *pcpu_create_chunk(void)

 	chunk->data = vms;
 	chunk->base_addr = vms[0]->addr - pcpu_group_offsets[0];
+	chunk->chunkno = ++chunkno;
+	printk("XXX chunk %d allocated base_addr=%p\n",
+	       chunk->chunkno, chunk->base_addr);
+	printk("XXX VMS:");
+	for (i = 0; i < pcpu_nr_groups; i++)
+		printk(" %zu@%p", vms[i]->size, vms[i]->addr);
+	printk("\n");
 	return chunk;
 }

diff --git a/mm/percpu.c b/mm/percpu.c
index 58c572b..8ef744d 100644
--- a/mm/percpu.c
+++ b/mm/percpu.c
@@ -90,7 +90,10 @@
 			 (unsigned long)__per_cpu_start)
 #endif

+static int chunkno;
+
 struct pcpu_chunk {
+	int			chunkno;
 	struct list_head	list;		/* linked to pcpu_slot lists */
 	int			free_size;	/* free bytes in the chunk */
 	int			contig_hint;	/* max contiguous size hint */
@@ -176,6 +179,40 @@ static struct list_head *pcpu_slot __read_mostly; /* chunk list slots */
 static void pcpu_reclaim(struct work_struct *work);
 static DECLARE_WORK(pcpu_reclaim_work, pcpu_reclaim);

+void pcpu_dump_chunk(struct pcpu_chunk *chunk)
+{
+	int i, contig = 0, free = 0;
+
+	printk("XXX   %d(f=%d,c=%d,u=%d,a=%d)", chunk->chunkno,
+	       chunk->free_size, chunk->contig_hint,
+	       chunk->map_used, chunk->map_alloc);
+	for (i = 0; i < chunk->map_used; i++) {
+		if (chunk->map[i] > 0) {
+			free += chunk->map[i];
+			contig = max(contig, chunk->map[i]);
+		}
+		printk(" %d", chunk->map[i]);
+	}
+	printk(" free=%d contig=%d%s\n", free, contig,
+	       (free != chunk->free_size || contig != chunk->contig_hint) ?
+	       " MISMATCH!" : "");
+}
+
+void pcpu_dump_chunk_slots(void)
+{
+	struct pcpu_chunk *chunk;
+	int i;
+
+	printk("XXX percpu allocator dump\n");
+	for (i = 0; i < pcpu_nr_slots; i++) {
+		if (list_empty(&pcpu_slot[i]))
+			continue;
+		printk("XXX  SLOT[%02d]\n", i);
+		list_for_each_entry(chunk, &pcpu_slot[i], list)
+			pcpu_dump_chunk(chunk);
+	}
+}
+
 static bool pcpu_addr_in_first_chunk(void *addr)
 {
 	void *first_start = pcpu_first_chunk->base_addr;
@@ -1011,6 +1048,19 @@ phys_addr_t per_cpu_ptr_to_phys(void *addr)
 		return page_to_phys(pcpu_addr_to_page(addr));
 }

+void per_cpu_ptr_to_phys_failed(void *addr)
+{
+	phys_addr_t phys;
+	unsigned long flags;
+
+	phys = per_cpu_ptr_to_phys(addr);
+	printk("XXX per_cpu_ptry_to_phys(%p) returned invalid address 0x%llx\n",
+	       addr, (unsigned long long)phys);
+	spin_lock_irqsave(&pcpu_lock, flags);
+	pcpu_dump_chunk_slots();
+	spin_unlock_irqrestore(&pcpu_lock, flags);
+}
+
 /**
  * pcpu_alloc_alloc_info - allocate percpu allocation info
  * @nr_groups: the number of groups
@@ -1426,6 +1476,11 @@ int __init pcpu_setup_first_chunk(const struct pcpu_alloc_info *ai,
 	pcpu_chunk_struct_size = sizeof(struct pcpu_chunk) +
 		BITS_TO_LONGS(pcpu_unit_pages) * sizeof(unsigned long);

+	printk("XXX CPU->UNIT M/O");
+	for_each_possible_cpu(cpu)
+		printk(" %d:%lx", unit_map[cpu], unit_off[cpu]);
+	printk("\n");
+
 	/*
 	 * Allocate chunk slots.  The additional last slot is for
 	 * empty chunks.
@@ -1435,6 +1490,10 @@ int __init pcpu_setup_first_chunk(const struct pcpu_alloc_info *ai,
 	for (i = 0; i < pcpu_nr_slots; i++)
 		INIT_LIST_HEAD(&pcpu_slot[i]);

+	printk("XXX ss=%zu up=%d us=%d ns=%d rs=%zd ds=%zd\n",
+	       ai->static_size, pcpu_unit_pages, pcpu_unit_size,
+	       pcpu_nr_slots, ai->reserved_size, dyn_size);
+
 	/*
 	 * Initialize static chunk.  If reserved_size is zero, the
 	 * static chunk covers static area + dynamic allocation area
@@ -1454,6 +1513,7 @@ int __init pcpu_setup_first_chunk(const struct pcpu_alloc_info *ai,
 		schunk->free_size = ai->reserved_size;
 		pcpu_reserved_chunk = schunk;
 		pcpu_reserved_chunk_limit = ai->static_size + ai->reserved_size;
+		schunk->chunkno = -1;
 	} else {
 		schunk->free_size = dyn_size;
 		dyn_size = 0;			/* dynamic area covered */
@@ -1483,6 +1543,12 @@ int __init pcpu_setup_first_chunk(const struct pcpu_alloc_info *ai,
 	pcpu_first_chunk = dchunk ?: schunk;
 	pcpu_chunk_relocate(pcpu_first_chunk, -1);

+	if (pcpu_reserved_chunk) {
+		printk("XXX reserved chunk\n");
+		pcpu_dump_chunk(pcpu_reserved_chunk);
+	}
+	pcpu_dump_chunk_slots();
+
 	/* we're done */
 	pcpu_base_addr = base_addr;
 	return 0;
@@ -1592,6 +1658,7 @@ int __init pcpu_embed_first_chunk(size_t reserved_size, size_t dyn_size,
 			goto out_free_areas;
 		}
 		areas[group] = ptr;
+		printk("XXX areas[%d]=%p\n", group, areas[group]);

 		base = min(ptr, base);

@@ -1608,12 +1675,15 @@ int __init pcpu_embed_first_chunk(size_t reserved_size, size_t dyn_size,
 	}

 	/* base address is now known, determine group base offsets */
+	printk("XXX base_addr=%p", base);
 	max_distance = 0;
 	for (group = 0; group < ai->nr_groups; group++) {
 		ai->groups[group].base_offset = areas[group] - base;
 		max_distance = max_t(size_t, max_distance,
 				     ai->groups[group].base_offset);
+		printk(" %lx", ai->groups[group].base_offset);
 	}
+	printk("\n");
 	max_distance += ai->unit_size;

 	/* warn if maximum distance is further than 75% of vmalloc space */

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

WARNING: multiple messages have this Message-ID (diff)
From: Tejun Heo <tj@kernel.org>
To: CAI Qian <caiqian@redhat.com>
Cc: linux-kernel <linux-kernel@vger.kernel.org>,
	Avi Kivity <avi@redhat.com>,
	Marcelo Tosatti <mtosatti@redhat.com>,
	dhowells@redhat.com, graff yang <graff.yang@gmail.com>,
	sonic adi <sonic.adi@gmail.com>,
	kexec <kexec@lists.infradead.org>,
	Chris Lalancette <clalance@redhat.com>
Subject: Re: kvm kdump regression
Date: Fri, 17 Sep 2010 17:22:07 +0200	[thread overview]
Message-ID: <4C93879F.6000201@kernel.org> (raw)
In-Reply-To: <391574593.869121284452994336.JavaMail.root@zmail06.collab.prod.int.phx2.redhat.com>

Hello,

Can you please apply the following patch, reproduce the problem and
report the kernel log?

Thanks.

diff --git a/arch/x86/kernel/crash_dump_64.c b/arch/x86/kernel/crash_dump_64.c
index 045b36c..8ac45a4 100644
--- a/arch/x86/kernel/crash_dump_64.c
+++ b/arch/x86/kernel/crash_dump_64.c
@@ -13,6 +13,7 @@
 /* Stores the physical address of elf header of crash image. */
 unsigned long long elfcorehdr_addr = ELFCORE_ADDR_MAX;

+void per_cpu_ptr_to_phys_failed(void *addr);
 /**
  * copy_oldmem_page - copy one page from "oldmem"
  * @pfn: page frame number to be copied
@@ -35,8 +36,10 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
 		return 0;

 	vaddr = ioremap(pfn << PAGE_SHIFT, PAGE_SIZE);
-	if (!vaddr)
+	if (!vaddr) {
+		per_cpu_ptr_to_phys_failed(vaddr);
 		return -ENOMEM;
+	}

 	if (userbuf) {
 		if (copy_to_user(buf, vaddr + offset, csize)) {
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 932eaee..3bbffb0 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -6540,6 +6540,8 @@ static void __init ata_parse_force_param(void)
 	ata_force_tbl_size = idx;
 }

+void per_cpu_ptr_to_phys_failed(void *addr);
+
 static int __init ata_init(void)
 {
 	int rc = -ENOMEM;
@@ -6553,6 +6555,7 @@ static int __init ata_init(void)
 	}

 	printk(KERN_DEBUG "libata version " DRV_VERSION " loaded.\n");
+	per_cpu_ptr_to_phys_failed(0x1234);
 	return 0;
 }

diff --git a/mm/percpu-vm.c b/mm/percpu-vm.c
index 7d9c1d0..357569a 100644
--- a/mm/percpu-vm.c
+++ b/mm/percpu-vm.c
@@ -415,6 +415,7 @@ static struct pcpu_chunk *pcpu_create_chunk(void)
 {
 	struct pcpu_chunk *chunk;
 	struct vm_struct **vms;
+	int i;

 	chunk = pcpu_alloc_chunk();
 	if (!chunk)
@@ -429,6 +430,13 @@ static struct pcpu_chunk *pcpu_create_chunk(void)

 	chunk->data = vms;
 	chunk->base_addr = vms[0]->addr - pcpu_group_offsets[0];
+	chunk->chunkno = ++chunkno;
+	printk("XXX chunk %d allocated base_addr=%p\n",
+	       chunk->chunkno, chunk->base_addr);
+	printk("XXX VMS:");
+	for (i = 0; i < pcpu_nr_groups; i++)
+		printk(" %zu@%p", vms[i]->size, vms[i]->addr);
+	printk("\n");
 	return chunk;
 }

diff --git a/mm/percpu.c b/mm/percpu.c
index 58c572b..8ef744d 100644
--- a/mm/percpu.c
+++ b/mm/percpu.c
@@ -90,7 +90,10 @@
 			 (unsigned long)__per_cpu_start)
 #endif

+static int chunkno;
+
 struct pcpu_chunk {
+	int			chunkno;
 	struct list_head	list;		/* linked to pcpu_slot lists */
 	int			free_size;	/* free bytes in the chunk */
 	int			contig_hint;	/* max contiguous size hint */
@@ -176,6 +179,40 @@ static struct list_head *pcpu_slot __read_mostly; /* chunk list slots */
 static void pcpu_reclaim(struct work_struct *work);
 static DECLARE_WORK(pcpu_reclaim_work, pcpu_reclaim);

+void pcpu_dump_chunk(struct pcpu_chunk *chunk)
+{
+	int i, contig = 0, free = 0;
+
+	printk("XXX   %d(f=%d,c=%d,u=%d,a=%d)", chunk->chunkno,
+	       chunk->free_size, chunk->contig_hint,
+	       chunk->map_used, chunk->map_alloc);
+	for (i = 0; i < chunk->map_used; i++) {
+		if (chunk->map[i] > 0) {
+			free += chunk->map[i];
+			contig = max(contig, chunk->map[i]);
+		}
+		printk(" %d", chunk->map[i]);
+	}
+	printk(" free=%d contig=%d%s\n", free, contig,
+	       (free != chunk->free_size || contig != chunk->contig_hint) ?
+	       " MISMATCH!" : "");
+}
+
+void pcpu_dump_chunk_slots(void)
+{
+	struct pcpu_chunk *chunk;
+	int i;
+
+	printk("XXX percpu allocator dump\n");
+	for (i = 0; i < pcpu_nr_slots; i++) {
+		if (list_empty(&pcpu_slot[i]))
+			continue;
+		printk("XXX  SLOT[%02d]\n", i);
+		list_for_each_entry(chunk, &pcpu_slot[i], list)
+			pcpu_dump_chunk(chunk);
+	}
+}
+
 static bool pcpu_addr_in_first_chunk(void *addr)
 {
 	void *first_start = pcpu_first_chunk->base_addr;
@@ -1011,6 +1048,19 @@ phys_addr_t per_cpu_ptr_to_phys(void *addr)
 		return page_to_phys(pcpu_addr_to_page(addr));
 }

+void per_cpu_ptr_to_phys_failed(void *addr)
+{
+	phys_addr_t phys;
+	unsigned long flags;
+
+	phys = per_cpu_ptr_to_phys(addr);
+	printk("XXX per_cpu_ptry_to_phys(%p) returned invalid address 0x%llx\n",
+	       addr, (unsigned long long)phys);
+	spin_lock_irqsave(&pcpu_lock, flags);
+	pcpu_dump_chunk_slots();
+	spin_unlock_irqrestore(&pcpu_lock, flags);
+}
+
 /**
  * pcpu_alloc_alloc_info - allocate percpu allocation info
  * @nr_groups: the number of groups
@@ -1426,6 +1476,11 @@ int __init pcpu_setup_first_chunk(const struct pcpu_alloc_info *ai,
 	pcpu_chunk_struct_size = sizeof(struct pcpu_chunk) +
 		BITS_TO_LONGS(pcpu_unit_pages) * sizeof(unsigned long);

+	printk("XXX CPU->UNIT M/O");
+	for_each_possible_cpu(cpu)
+		printk(" %d:%lx", unit_map[cpu], unit_off[cpu]);
+	printk("\n");
+
 	/*
 	 * Allocate chunk slots.  The additional last slot is for
 	 * empty chunks.
@@ -1435,6 +1490,10 @@ int __init pcpu_setup_first_chunk(const struct pcpu_alloc_info *ai,
 	for (i = 0; i < pcpu_nr_slots; i++)
 		INIT_LIST_HEAD(&pcpu_slot[i]);

+	printk("XXX ss=%zu up=%d us=%d ns=%d rs=%zd ds=%zd\n",
+	       ai->static_size, pcpu_unit_pages, pcpu_unit_size,
+	       pcpu_nr_slots, ai->reserved_size, dyn_size);
+
 	/*
 	 * Initialize static chunk.  If reserved_size is zero, the
 	 * static chunk covers static area + dynamic allocation area
@@ -1454,6 +1513,7 @@ int __init pcpu_setup_first_chunk(const struct pcpu_alloc_info *ai,
 		schunk->free_size = ai->reserved_size;
 		pcpu_reserved_chunk = schunk;
 		pcpu_reserved_chunk_limit = ai->static_size + ai->reserved_size;
+		schunk->chunkno = -1;
 	} else {
 		schunk->free_size = dyn_size;
 		dyn_size = 0;			/* dynamic area covered */
@@ -1483,6 +1543,12 @@ int __init pcpu_setup_first_chunk(const struct pcpu_alloc_info *ai,
 	pcpu_first_chunk = dchunk ?: schunk;
 	pcpu_chunk_relocate(pcpu_first_chunk, -1);

+	if (pcpu_reserved_chunk) {
+		printk("XXX reserved chunk\n");
+		pcpu_dump_chunk(pcpu_reserved_chunk);
+	}
+	pcpu_dump_chunk_slots();
+
 	/* we're done */
 	pcpu_base_addr = base_addr;
 	return 0;
@@ -1592,6 +1658,7 @@ int __init pcpu_embed_first_chunk(size_t reserved_size, size_t dyn_size,
 			goto out_free_areas;
 		}
 		areas[group] = ptr;
+		printk("XXX areas[%d]=%p\n", group, areas[group]);

 		base = min(ptr, base);

@@ -1608,12 +1675,15 @@ int __init pcpu_embed_first_chunk(size_t reserved_size, size_t dyn_size,
 	}

 	/* base address is now known, determine group base offsets */
+	printk("XXX base_addr=%p", base);
 	max_distance = 0;
 	for (group = 0; group < ai->nr_groups; group++) {
 		ai->groups[group].base_offset = areas[group] - base;
 		max_distance = max_t(size_t, max_distance,
 				     ai->groups[group].base_offset);
+		printk(" %lx", ai->groups[group].base_offset);
 	}
+	printk("\n");
 	max_distance += ai->unit_size;

 	/* warn if maximum distance is further than 75% of vmalloc space */

  reply	other threads:[~2010-09-17 15:22 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-09-14  3:09 kvm kdump regression CAI Qian
2010-09-14  3:09 ` CAI Qian
2010-09-14  8:26 ` Tejun Heo
2010-09-14  8:26   ` Tejun Heo
2010-09-14  8:29   ` CAI Qian
2010-09-14  8:29     ` CAI Qian
2010-09-17 15:22     ` Tejun Heo [this message]
2010-09-17 15:22       ` Tejun Heo
2010-09-18 12:36       ` CAI Qian
2010-09-18 12:36         ` CAI Qian
2010-09-19 15:02         ` Tejun Heo
2010-09-19 15:02           ` Tejun Heo
2010-09-20  8:00           ` CAI Qian
2010-09-20  8:00             ` CAI Qian
2010-09-20  9:12             ` Tejun Heo
2010-09-20  9:12               ` Tejun Heo
2010-09-20  9:44               ` CAI Qian
2010-09-20  9:44                 ` CAI Qian
2010-09-20  9:49                 ` CAI Qian
2010-09-20  9:49                   ` CAI Qian
     [not found] <1888861854.1349971284977836487.JavaMail.root@zmail06.collab.prod.int.phx2.redhat.com>
2010-09-20 10:17 ` caiqian
2010-09-20 10:17   ` caiqian
2010-09-20 23:09   ` Tejun Heo
2010-09-20 23:09     ` Tejun Heo
2010-09-21  0:40     ` CAI Qian
2010-09-21  0:40       ` CAI Qian

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=4C93879F.6000201@kernel.org \
    --to=tj@kernel.org \
    --cc=avi@redhat.com \
    --cc=caiqian@redhat.com \
    --cc=clalance@redhat.com \
    --cc=dhowells@redhat.com \
    --cc=graff.yang@gmail.com \
    --cc=kexec@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mtosatti@redhat.com \
    --cc=sonic.adi@gmail.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.