From: "Song Bao Hua (Barry Song)" <song.bao.hua@hisilicon.com>
To: Jan Kiszka <jan.kiszka@siemens.com>,
"kieran.bingham@ideasonboard.com"
<kieran.bingham@ideasonboard.com>,
"corbet@lwn.net" <corbet@lwn.net>,
"linux-doc@vger.kernel.org" <linux-doc@vger.kernel.org>
Cc: "linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
"linuxarm@openeuler.org" <linuxarm@openeuler.org>
Subject: RE: [PATCH] scripts/gdb: document lx_current is only supported by x86
Date: Tue, 23 Feb 2021 21:27:58 +0000 [thread overview]
Message-ID: <d6266e0e5f714187abbc77b78141be59@hisilicon.com> (raw)
In-Reply-To: <940e936d-d35b-105c-201c-8f2126222d15@siemens.com>
> -----Original Message-----
> From: Song Bao Hua (Barry Song)
> Sent: Tuesday, February 23, 2021 9:30 PM
> To: 'Jan Kiszka' <jan.kiszka@siemens.com>; kieran.bingham@ideasonboard.com;
> corbet@lwn.net; linux-doc@vger.kernel.org
> Cc: linux-kernel@vger.kernel.org; linuxarm@openeuler.org
> Subject: RE: [PATCH] scripts/gdb: document lx_current is only supported by x86
>
>
>
> > -----Original Message-----
> > From: Jan Kiszka [mailto:jan.kiszka@siemens.com]
> > Sent: Tuesday, February 23, 2021 8:27 PM
> > To: Song Bao Hua (Barry Song) <song.bao.hua@hisilicon.com>;
> > kieran.bingham@ideasonboard.com; corbet@lwn.net; linux-doc@vger.kernel.org
> > Cc: linux-kernel@vger.kernel.org; linuxarm@openeuler.org
> > Subject: Re: [PATCH] scripts/gdb: document lx_current is only supported by
> x86
> >
> > On 22.02.21 22:18, Song Bao Hua (Barry Song) wrote:
> > >
> > >
> > >> -----Original Message-----
> > >> From: Kieran Bingham [mailto:kieran.bingham@ideasonboard.com]
> > >> Sent: Tuesday, February 23, 2021 12:06 AM
> > >> To: Song Bao Hua (Barry Song) <song.bao.hua@hisilicon.com>; corbet@lwn.net;
> > >> linux-doc@vger.kernel.org; jan.kiszka@siemens.com
> > >> Cc: linux-kernel@vger.kernel.org; linuxarm@openeuler.org
> > >> Subject: Re: [PATCH] scripts/gdb: document lx_current is only supported
> by
> > x86
> > >>
> > >> Hi Barry
> > >>
> > >> On 21/02/2021 21:35, Barry Song wrote:
> > >>> lx_current depends on the per_cpu current_task which exists on x86 only:
> > >>>
> > >>> arch$ git grep current_task | grep -i per_cpu
> > >>> x86/include/asm/current.h:DECLARE_PER_CPU(struct task_struct *,
> > >> current_task);
> > >>> x86/kernel/cpu/common.c:DEFINE_PER_CPU(struct task_struct *,
> > current_task)
> > >> ____cacheline_aligned =
> > >>> x86/kernel/cpu/common.c:EXPORT_PER_CPU_SYMBOL(current_task);
> > >>> x86/kernel/cpu/common.c:DEFINE_PER_CPU(struct task_struct *,
> > current_task)
> > >> = &init_task;
> > >>> x86/kernel/cpu/common.c:EXPORT_PER_CPU_SYMBOL(current_task);
> > >>> x86/kernel/smpboot.c: per_cpu(current_task, cpu) = idle;
> > >>>
> > >>> On other architectures, lx_current() will lead to a python exception:
> > >>> (gdb) p $lx_current().pid
> > >>> Python Exception <class 'gdb.error'> No symbol "current_task" in current
> > >> context.:
> > >>> Error occurred in Python: No symbol "current_task" in current context.
> > >>>
> > >>> To avoid more people struggling and wasting time in other architectures,
> > >>> document it.
> > >>>
> > >>> Cc: Jan Kiszka <jan.kiszka@siemens.com>
> > >>> Signed-off-by: Barry Song <song.bao.hua@hisilicon.com>
> > >>> ---
> > >>> Documentation/dev-tools/gdb-kernel-debugging.rst | 2 +-
> > >>> scripts/gdb/linux/cpus.py | 10 ++++++++--
> > >>> 2 files changed, 9 insertions(+), 3 deletions(-)
> > >>>
> > >>> diff --git a/Documentation/dev-tools/gdb-kernel-debugging.rst
> > >> b/Documentation/dev-tools/gdb-kernel-debugging.rst
> > >>> index 4756f6b3a04e..1586901b683c 100644
> > >>> --- a/Documentation/dev-tools/gdb-kernel-debugging.rst
> > >>> +++ b/Documentation/dev-tools/gdb-kernel-debugging.rst
> > >>> @@ -114,7 +114,7 @@ Examples of using the Linux-provided gdb helpers
> > >>> [ 0.000000] BIOS-e820: [mem
> > 0x000000000009fc00-0x000000000009ffff]
> > >> reserved
> > >>> ....
> > >>>
> > >>> -- Examine fields of the current task struct::
> > >>> +- Examine fields of the current task struct(supported by x86 only)::
> > >>>
> > >>> (gdb) p $lx_current().pid
> > >>> $1 = 4998
> > >>> diff --git a/scripts/gdb/linux/cpus.py b/scripts/gdb/linux/cpus.py
> > >>> index 008e62f3190d..f382762509d3 100644
> > >>> --- a/scripts/gdb/linux/cpus.py
> > >>> +++ b/scripts/gdb/linux/cpus.py
> > >>> @@ -156,6 +156,13 @@ Note that VAR has to be quoted as string."""
> > >>>
> > >>> PerCpu()
> > >>>
> > >>> +def get_current_task(cpu):
> > >>> + if utils.is_target_arch("x86"):
> > >>> + var_ptr = gdb.parse_and_eval("¤t_task")
> > >>> + return per_cpu(var_ptr, cpu).dereference()
> > >>> + else:
> > >>> + raise gdb.GdbError("Sorry, obtaining the current task is not yet
> > "
> > >>> + "supported with this arch")
> > >>
> > >> I've wondered in the past how we should handle the architecture specific
> > >> layers.
> > >>
> > >> Perhaps we need to have an interface of functionality to implement on
> > >> each architecture so that we can create a per-arch set of helpers.
> > >>
> > >> or break it up into arch specific subdirs at least...
> > >>
> > >>
> > >>> class LxCurrentFunc(gdb.Function):
> > >>> """Return current task.
> > >>> @@ -167,8 +174,7 @@ number. If CPU is omitted, the CPU of the current
> context
> > >> is used."""
> > >>> super(LxCurrentFunc, self).__init__("lx_current")
> > >>>
> > >>> def invoke(self, cpu=-1):
> > >>> - var_ptr = gdb.parse_and_eval("¤t_task")
> > >>> - return per_cpu(var_ptr, cpu).dereference()
> > >>> + return get_current_task(cpu)
> > >>>
> > >>
> > >> And then perhaps we simply shouldn't even expose commands which can not
> > >> be supported on those architectures?
> > >
> > > I feel it is better to tell users this function is not supported on its
> arch
> > > than simply hiding the function.
> > >
> > > If we hide it, users still have many chances to try it as they have got
> > > information of lx_current from google or somewhere.
> > > They will try, if it turns out the lx_current is not in the list and an
> > > error like "invalid data type for function to be called", they will
> > > probably suspect their gdb/python environment is not set up correctly,
> > > and continue to waste time in checking their environment.
> > > Finally they figure out this function is not supported by its arch so it
> is
> > > not exposed. But they have wasted a couple of hours before knowing that.
> > >
> > > It seems it is more friendly to directly tell users this is not supported
> > > on its arch explicitly and clearly than reporting a "invalid data type
> > > for function to be called.
> > >
> > >>
> > >> Is it easy to disable this command if it's not supportable on the
> > >> architecture?
> > >>
> > >
> > > TBH, I'm not a python expert. I don't know how to do that in an elegant
> > > way :-) on the other hand, it seems lx_current isn’t a command like
> > > lx-dmesg. Lx_current is actually similar with lx_per_cpu, we use gdb's
> > > print(p) command to show its content.
> > >
> > >> Presumably you are working on non-x86, have you investigated adding this
> > >> support for your architecture (arm/arm64?)?
> > >
> > > Yes. I've thought about it. But It would be quite trivial to bring up
> > > this function on arm64.
> > >
> > > arch/arm64/include/asm/current.h:
> > > static __always_inline struct task_struct *get_current(void)
> > > {
> > > unsigned long sp_el0;
> > >
> > > asm ("mrs %0, sp_el0" : "=r" (sp_el0));
> > >
> > > return (struct task_struct *)sp_el0;
> > > }
> > >
> > > We have to read a special register named sp_el0 and convert it to
> > > task_struct while we are running in kernel mode. In gdb I can do
> > > it by:
> > > (gdb)p/x $SP_EL0
> > > $20 = 0xffffffc011492400
> > > (gdb)p ((struct task_struct *0xffffffc011492400))->pid
> > > $21 = 0
> > >
> > > What is more complex is that if we are running in user mode(EL0), this
> > > register doesn't describe current task any more. so we have to
> > > differentiate the modes of processor and make sure it only returns
> > > current task while we are running in EL1(processor's kernel mode).
> >
> > Is all information needed for this available via gdb?
>
> I can't read current EL level from gdb as CurrentEL is not readable
> from EL0 as shown on the ARMv8 manual C5.2.1:
> "CurrentEL, Current Exception Level" section "Accessibility".
> Trying to run it in Linux userland raises SIGILL.
>
> But a workaround I can do is that while running in kernel, SP_EL0
> is a value like 0xffffxxxx xxxxxxxx; otherwise, it would be a value
> like 0x0000xxxx xxxxxxxx.
>
> So I could actually implement lx_current on arm64 by:
>
> p/x $SP_EL0
> if value > 0xffff00000000000
> task_struct_addr = value
> else
> userspace, no current
>
> the problem is that I don't know how to read the register and
> transfer address into task_struct in gdb/scripts. Would you
> like to share some example code if you have?
It is not difficult. I have managed to implement a prototype
on arm64:
diff --git a/scripts/gdb/linux/cpus.py b/scripts/gdb/linux/cpus.py
index f382762509d3..b53ffc35a92f 100644
--- a/scripts/gdb/linux/cpus.py
+++ b/scripts/gdb/linux/cpus.py
@@ -16,6 +16,9 @@ import gdb
from linux import tasks, utils
+task_type = utils.CachedType("struct task_struct")
+
+
MAX_CPUS = 4096
@@ -157,9 +160,15 @@ Note that VAR has to be quoted as string."""
PerCpu()
def get_current_task(cpu):
+ task_ptr_type = task_type.get_type().pointer()
+
if utils.is_target_arch("x86"):
var_ptr = gdb.parse_and_eval("¤t_task")
return per_cpu(var_ptr, cpu).dereference()
+ elif utils.is_target_arch("aarch64"):
+ current_task_addr = gdb.parse_and_eval("$SP_EL0")
+ current_task = current_task_addr.cast(task_ptr_type)
+ return current_task.dereference()
else:
raise gdb.GdbError("Sorry, obtaining the current task is not yet "
"supported with this arch")
I am able to get the current task now on arm64:
(gdb) p $lx_current().pid
$1 = 0
(gdb) p $lx_current().comm
$2 = "swapper/0\000\000\000\000\000\000"
I will increase the code to make sure $SP_EL0 is a valid current, then
send v2 to support arm64.
>
> >
> > >
> > >>
> > >> The fact you have run the command implies it would be useful for you ?
> > >>
> > >
> > > Yes. I think it is a common requirement to get current task. lx_current
> > > convenience function can help everyone. Since there is a document saying
> > > this command exists, everyone using scripts/gdb would like to try it
> > > I guess.
> > >
> > > The simplest way would be adding current_task per_cpu variable for other
> > > arch, but I believe hardly arch maintainers will accept it as its only
> > > benefit is bringing up the lx_current. So 99.9% no maintainer wants it.
> > >
> > > Thus, for the time being, I moved to just stop people from wasting time
> > > like what I had done with a couple of hours.
> > >
> >
> > I agree with the warning, also as potential motivation to add support
> > for other archs.
> >
>
> Yep.
At least motivated me to add support on arm64.
>
> > Jan
> >
> > --
> > Siemens AG, T RDA IOT
> > Corporate Competence Center Embedded Linux
>
Thanks
Barry
prev parent reply other threads:[~2021-02-23 21:29 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-02-21 21:35 Barry Song
2021-02-22 11:06 ` Kieran Bingham
2021-02-22 21:18 ` Song Bao Hua (Barry Song)
2021-02-23 7:26 ` Jan Kiszka
2021-02-23 8:36 ` Song Bao Hua (Barry Song)
2021-02-23 21:27 ` Song Bao Hua (Barry Song) [this message]
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=d6266e0e5f714187abbc77b78141be59@hisilicon.com \
--to=song.bao.hua@hisilicon.com \
--cc=corbet@lwn.net \
--cc=jan.kiszka@siemens.com \
--cc=kieran.bingham@ideasonboard.com \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linuxarm@openeuler.org \
/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
all inboxes | Powered by JetHome®