public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
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: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-09-14  3:09 kvm kdump regression CAI Qian
2010-09-14  8:26 ` Tejun Heo
2010-09-14  8:29   ` CAI Qian
2010-09-17 15:22     ` Tejun Heo [this message]
2010-09-18 12:36       ` CAI Qian
2010-09-19 15:02         ` Tejun Heo
2010-09-20  8:00           ` CAI Qian
2010-09-20  9:12             ` Tejun Heo
2010-09-20  9:44               ` 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 23:09   ` Tejun Heo
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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox