Re: [PATCH] ARM SMP

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



----- "Per Fransson" <per.xx.fransson@xxxxxxxxxxxxxx> wrote:

> Hi Dave,
> 
> This patch is an attempt to get the ball rolling on SMP support for ARM.
> 
> Regards,
> Per

Aside from a few minor issues when compiling arm.c with "make warn",
this patch looks fine to me, and runs OK on a sample UP vmlinux/vmcore
pair that Mika made available for me.

For a sanity check, though, can I get an ACK from the ARM maintainers
(Mika, Jan, and/or Thomas) prior to merging it?  

Also, it would be helpful to me if you could make an ARM SMP vmlinux/vmcore
pair for me to have around as a reference.  If you can do it, please make
the dumpfile as small in memory-size as possible, and put it somewhere that
I can download from.  (you can send me the details off-list).

Thanks,
  Dave
 
 
> diff --git a/arm.c b/arm.c
> index 06b2f1c..bf346df 100644
> --- a/arm.c
> +++ b/arm.c
> @@ -73,7 +73,7 @@ struct arm_cpu_context_save {
>  /*
>   * Holds registers during the crash.
>   */
> -static struct arm_pt_regs panic_task_regs;
> +static struct arm_pt_regs *panic_task_regs;
> 
>  #define PGDIR_SIZE() (4 * PAGESIZE())
>  #define PGDIR_OFFSET(X) (((ulong)(X)) & (PGDIR_SIZE() - 1))
> @@ -484,71 +484,103 @@ arm_get_crash_notes(void)
>  	Elf32_Nhdr *note;
>  	ulong ptr, offset;
>  	char *buf, *p;
> +	ulong *notes_ptrs;
> +	ulong per_cpu_offsets_addr;
> +	ulong *per_cpu_offsets;
> +	ulong i;
> 
>  	if (!symbol_exists("crash_notes"))
>  		return FALSE;
> 
>  	crash_notes = symbol_value("crash_notes");
> 
> -	if (kt->cpus > 1)
> -		error(WARNING, "only one CPU is currently supported\n");
> +	notes_ptrs = GETBUF(kt->cpus*sizeof(notes_ptrs[0]));
> 
>  	/*
>  	 * Read crash_notes for the first CPU. crash_notes are in standard
> ELF
>  	 * note format.
>  	 */
> -	if (!readmem(crash_notes, KVADDR, &ptr, sizeof(ptr), "crash_notes",
> +	if (!readmem(crash_notes, KVADDR, &notes_ptrs[kt->cpus-1],
> sizeof(notes_ptrs[kt->cpus-1]), "crash_notes",
>  		     RETURN_ON_ERROR)) {
> -		error(WARNING, "cannot read crash_notes\n");
> +	    error(WARNING, "cannot read crash_notes\n");
> +	    return FALSE;
> +	}
> +	
> +
> +	if (symbol_exists("__per_cpu_offset")) {
> +
> +	    /* Get the __per_cpu_offset array */
> +	    per_cpu_offsets_addr = symbol_value("__per_cpu_offset");
> +	
> +	    per_cpu_offsets = GETBUF(kt->cpus*sizeof(*per_cpu_offsets));
> +
> +	    if (!readmem(per_cpu_offsets_addr, KVADDR, per_cpu_offsets,
> kt->cpus*sizeof(*per_cpu_offsets), "per_cpu_offsets",
> +			 RETURN_ON_ERROR)) {
> +		error(WARNING, "cannot read per_cpu_offsets\n");
>  		return FALSE;
> +	    }
> +
> +	    /* Add __per_cpu_offset for each cpu to form the pointer to the
> notes */
> +	    for (i = 0; i<kt->cpus; i++) {
> +		notes_ptrs[i] = notes_ptrs[kt->cpus-1] + per_cpu_offsets[i];
> +	    }
> +	    FREEBUF(per_cpu_offsets);
>  	}
> 
>  	buf = GETBUF(SIZE(note_buf));
> +	panic_task_regs = GETBUF(kt->cpus*sizeof(*panic_task_regs));
> +	
> +	for  (i=0;i<kt->cpus;i++) {
> 
> -	if (!readmem(ptr, KVADDR, buf, SIZE(note_buf), "note_buf_t",
> -		     RETURN_ON_ERROR)) {
> +	    if (!readmem(notes_ptrs[i], KVADDR, buf, SIZE(note_buf),
> "note_buf_t",
> +			 RETURN_ON_ERROR)) {
>  		error(WARNING, "failed to read note_buf_t\n");
>  		goto fail;
> -	}
> +	    }
> 
> -	/*
> -	 * Do some sanity checks for this note before reading registers from
> it.
> -	 */
> -	note = (Elf32_Nhdr *)buf;
> -	p = buf + sizeof(Elf32_Nhdr);
> +	    /*
> +	     * Do some sanity checks for this note before reading registers
> from it.
> +	     */
> +	    note = (Elf32_Nhdr *)buf;
> +	    p = buf + sizeof(Elf32_Nhdr);
> 
> -	if (note->n_type != NT_PRSTATUS) {
> +	    if (note->n_type != NT_PRSTATUS) {
>  		error(WARNING, "invalid note (n_type != NT_PRSTATUS)\n");
>  		goto fail;
> -	}
> -	if (p[0] != 'C' || p[1] != 'O' || p[2] != 'R' || p[3] != 'E') {
> +	    }
> +	    if (p[0] != 'C' || p[1] != 'O' || p[2] != 'R' || p[3] != 'E') {
>  		error(WARNING, "invalid note (name != \"CORE\"\n");
>  		goto fail;
> -	}
> +	    }
> 
> -	/*
> -	 * Find correct location of note data. This contains elf_prstatus
> -	 * structure which has registers etc. for the crashed task.
> -	 */
> -	offset = sizeof(Elf32_Nhdr);
> -	offset = roundup(offset + note->n_namesz, 4);
> -	p = buf + offset; /* start of elf_prstatus */
> +	    /*
> +	     * Find correct location of note data. This contains
> elf_prstatus
> +	     * structure which has registers etc. for the crashed task.
> +	     */
> +	    offset = sizeof(Elf32_Nhdr);
> +	    offset = roundup(offset + note->n_namesz, 4);
> +	    p = buf + offset; /* start of elf_prstatus */
> 
> -	BCOPY(p + OFFSET(elf_prstatus_pr_reg), &panic_task_regs,
> -	      sizeof(panic_task_regs));
> +	    BCOPY(p + OFFSET(elf_prstatus_pr_reg), &panic_task_regs[i],
> +		  sizeof(panic_task_regs[i]));
> +
> +	}
> 
>  	/*
>  	 * And finally we have pid and registers for the crashed task. This
> is
>  	 * used later on when dumping backtrace.
>  	 */
>  	ms->crash_task_pid = *(ulong *)(p + OFFSET(elf_prstatus_pr_pid));
> -	ms->crash_task_regs = &panic_task_regs;
> +	ms->crash_task_regs = panic_task_regs;
> 
>  	FREEBUF(buf);
> +	FREEBUF(notes_ptrs);
>  	return TRUE;
> 
>  fail:
>  	FREEBUF(buf);
> +	FREEBUF(notes_ptrs);
> +	FREEBUF(panic_task_regs);
>  	return FALSE;
>  }
> 
> @@ -996,20 +1028,20 @@ arm_get_dumpfile_stack_frame(struct bt_info
> *bt, ulong *nip, ulong *ksp)
>  	if (!ms->crash_task_regs)
>  		return FALSE;
> 
> -	if (tt->panic_task != bt->task || bt->tc->pid !=
> ms->crash_task_pid)
> -		return FALSE;
> -
> +	if (!is_task_active(bt->task))
> +	    return FALSE;
> +	
>  	/*
>  	 * We got registers for panic task from crash_notes. Just return
> them.
>  	 */
> -	*nip = ms->crash_task_regs->ARM_pc;
> -	*ksp = ms->crash_task_regs->ARM_sp;
> +	*nip = ms->crash_task_regs[bt->tc->processor].ARM_pc;
> +	*ksp = ms->crash_task_regs[bt->tc->processor].ARM_sp;
> 
>  	/*
>  	 * Also store pointer to all registers in case unwinding code needs
>  	 * to access LR.
>  	 */
> -	bt->machdep = ms->crash_task_regs;
> +	bt->machdep = &(ms->crash_task_regs[bt->tc->processor]);
> 
>  	return TRUE;
>  }
> diff --git a/defs.h b/defs.h
> index d431d6e..8a2291a 100755
> --- a/defs.h
> +++ b/defs.h
> @@ -85,7 +85,7 @@
>  #define NR_CPUS  (64)
>  #endif
>  #ifdef ARM
> -#define NR_CPUS  (1)
> +#define NR_CPUS  (4)
>  #endif
> 
>  #define BUFSIZE  (1500)
> 
> --
> Crash-utility mailing list
> Crash-utility@xxxxxxxxxx
> https://www.redhat.com/mailman/listinfo/crash-utility

--
Crash-utility mailing list
Crash-utility@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/crash-utility


[Index of Archives]     [Fedora Development]     [Fedora Desktop]     [Fedora SELinux]     [Yosemite News]     [KDE Users]     [Fedora Tools]

 

Powered by Linux