linux-mips
[Top] [All Lists]

Re: [PATCH 2/2] MIPS: get schedule_mfi info from __schedule

To: Tony Wu <tung7970@gmail.com>
Subject: Re: [PATCH 2/2] MIPS: get schedule_mfi info from __schedule
From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
Date: Thu, 09 May 2013 19:11:43 +0400
Cc: ralf@linux-mips.org, linux-mips@linux-mips.org
In-reply-to: <20130509144911.GD3562@hades>
List-archive: <http://www.linux-mips.org/archives/linux-mips/>
List-help: <mailto:ecartis@linux-mips.org?Subject=help>
List-id: linux-mips <linux-mips.eddie.linux-mips.org>
List-owner: <mailto:ralf@linux-mips.org>
List-post: <mailto:linux-mips@linux-mips.org>
List-software: Ecartis version 1.0.0
List-subscribe: <mailto:ecartis@linux-mips.org?subject=subscribe%20linux-mips>
List-unsubscribe: <mailto:ecartis@linux-mips.org?subject=unsubscribe%20linux-mips>
Original-recipient: rfc822;linux-mips@linux-mips.org
References: <20130509144911.GD3562@hades>
Sender: linux-mips-bounce@linux-mips.org
User-agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:16.0) Gecko/20121010 Thunderbird/16.0.1
Hello.

On 09-05-2013 18:49, Tony Wu wrote:

schedule_mfi is supposed to be extracted from schedule(), and
is used in thread_saved_pc and get_wchan.

But, after optimization, schedule() is reduced to a sibling
call to __schedule(), and no real frame info can be extracted.

One solution is to compile schedule() with -fno-omit-frame-pointer
and -fno-optimize-sibling-calls, but that will incur performance
degradation.

This patch follows the sibling call and extracts the
schedule_mfi from the __schedule with and without KALLSYMS enabled.

Signed-off-by: Tony Wu <tung7970@gmail.com>
---
  arch/mips/kernel/process.c |   28 ++++++++++++++++++++++++++--
  1 file changed, 26 insertions(+), 2 deletions(-)

diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index a794eb5..289ea69 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -314,15 +314,39 @@ err:

  static struct mips_frame_info schedule_mfi __read_mostly;

+static unsigned long get___schedule_addr(void)
+{
+#ifdef CONFIG_KALLSYMS
+       return kallsyms_lookup_name("__schedule");
+#else
+       union mips_instruction *ip = (void *)schedule;
+       int max_insns = 8;
+       int i;
+
+       for (i = 0; i < max_insns; i++, ip++) {
+               if (ip->j_format.opcode == j_op)
+                       return J_TARGET(ip, ip->j_format.target);
+       }
+       return 0;
+#endif
+}
+

    #ifdef's inside function body are frowned upon. Better code it as:

#ifdef CONFIG_KALLSYMS
static unsigned long get___schedule_addr(void)
{
        return kallsyms_lookup_name("__schedule");
}
#else
static unsigned long get___schedule_addr(void)
{
        union mips_instruction *ip = (void *)schedule;
[...]
        return 0;
}
#endif

WBR, Sergei


<Prev in Thread] Current Thread [Next in Thread>