Many serial driver triggers a lockdep warning for if tty_flip_buffer_push() is
called with uart_port->lock locked. This never shows up on UP kernels and comes
up only on SMP kernels.
Crash looks like this (produced with samsung.c driver):
-----
[<c0014d58>] (unwind_backtrace+0x0/0xf8) from [<c0011908>] (show_stack+0x10/0x14)
[<c0011908>] (show_stack+0x10/0x14) from [<c035da34>] (dump_stack+0x6c/0xac)
[<c035da34>] (dump_stack+0x6c/0xac) from [<c01b59ac>] (do_raw_spin_unlock+0xc4/0xd8)
[<c01b59ac>] (do_raw_spin_unlock+0xc4/0xd8) from [<c03627e4>] (_raw_spin_unlock_irqrestore+0xc/0)
[<c03627e4>] (_raw_spin_unlock_irqrestore+0xc/0x38) from [<c020a1a8>] (s3c24xx_serial_rx_chars+0)
[<c020a1a8>] (s3c24xx_serial_rx_chars+0x12c/0x260) from [<c020aae8>] (s3c64xx_serial_handle_irq+)
[<c020aae8>] (s3c64xx_serial_handle_irq+0x48/0x60) from [<c006aaa0>] (handle_irq_event_percpu+0x)
[<c006aaa0>] (handle_irq_event_percpu+0x50/0x194) from [<c006ac20>] (handle_irq_event+0x3c/0x5c)
[<c006ac20>] (handle_irq_event+0x3c/0x5c) from [<c006d864>] (handle_fasteoi_irq+0x80/0x13c)
[<c006d864>] (handle_fasteoi_irq+0x80/0x13c) from [<c006a4a4>] (generic_handle_irq+0x20/0x30)
[<c006a4a4>] (generic_handle_irq+0x20/0x30) from [<c000f454>] (handle_IRQ+0x38/0x94)
[<c000f454>] (handle_IRQ+0x38/0x94) from [<c0008538>] (gic_handle_irq+0x34/0x68)
[<c0008538>] (gic_handle_irq+0x34/0x68) from [<c00123c0>] (__irq_svc+0x40/0x70)
Exception stack(0xc04cdf70 to 0xc04cdfb8)
df60: 00000000 00000000 0000166e 00000000
df80: c04cc000 c050278f c050278f 00000001 c04d444c 410fc0f4 c03649b0 00000000
dfa0: 00000001 c04cdfb8 c000f758 c000f75c 60070013 ffffffff
[<c00123c0>] (__irq_svc+0x40/0x70) from [<c000f75c>] (arch_cpu_idle+0x28/0x30)
[<c000f75c>] (arch_cpu_idle+0x28/0x30) from [<c0054888>] (cpu_startup_entry+0x5c/0x148)
[<c0054888>] (cpu_startup_entry+0x5c/0x148) from [<c0497aa4>] (start_kernel+0x334/0x38c)
BUG: spinlock lockup suspected on CPU#0, kworker/0:1/360
lock: s3c24xx_serial_ports+0x1d8/0x370, .magic: dead4ead, .owner: <none>/-1, .owner_cpu: -1
CPU: 0 PID: 360 Comm: kworker/0:1 Not tainted 3.11.0-rc6-next-20130819-00003-g75485f1 #2
Workqueue: events flush_to_ldisc
[<c0014d58>] (unwind_backtrace+0x0/0xf8) from [<c0011908>] (show_stack+0x10/0x14)
[<c0011908>] (show_stack+0x10/0x14) from [<c035da34>] (dump_stack+0x6c/0xac)
[<c035da34>] (dump_stack+0x6c/0xac) from [<c01b581c>] (do_raw_spin_lock+0x100/0x17c)
[<c01b581c>] (do_raw_spin_lock+0x100/0x17c) from [<c03628a0>] (_raw_spin_lock_irqsave+0x20/0x28)
[<c03628a0>] (_raw_spin_lock_irqsave+0x20/0x28) from [<c0203224>] (uart_start+0x18/0x34)
[<c0203224>] (uart_start+0x18/0x34) from [<c01ef890>] (__receive_buf+0x4b4/0x738)
[<c01ef890>] (__receive_buf+0x4b4/0x738) from [<c01efb44>] (n_tty_receive_buf2+0x30/0x98)
[<c01efb44>] (n_tty_receive_buf2+0x30/0x98) from [<c01f2ba8>] (flush_to_ldisc+0xec/0x138)
[<c01f2ba8>] (flush_to_ldisc+0xec/0x138) from [<c0031af0>] (process_one_work+0xfc/0x348)
[<c0031af0>] (process_one_work+0xfc/0x348) from [<c0032138>] (worker_thread+0x138/0x37c)
[<c0032138>] (worker_thread+0x138/0x37c) from [<c0037a7c>] (kthread+0xa4/0xb0)
[<c0037a7c>] (kthread+0xa4/0xb0) from [<c000e5f8>] (ret_from_fork+0x14/0x3c)
-----
This patchset modifies these drivers to release the port lock before calling
tty_flip_buffer_push() and reacquire it after the call.
Similar stuff was already done for few other drivers in the past, like:
commit 2389b272168ceec056ca1d8a870a97fa9c26e11a
Author: Thomas Gleixner <tglx(a)linutronix.de>
Date: Tue May 29 21:53:50 2007 +0100
[ARM] 4417/1: Serial: Fix AMBA drivers locking
This is build tested for all drivers and tested on Samsung's Arndale board for
samsung.c driver. Rebased over linux-next (Problem was reproduced on this
branch):
commit 1e712b0818569846d6b926ecb6bf32b3dea73609
Author: Stephen Rothwell <sfr(a)canb.auug.org.au>
Date: Fri Aug 16 17:06:26 2013 +1000
Add linux-next specific files for 20130816
Signed-off-by: Stephen Rothwell <sfr(a)canb.auug.org.au>
Cc: Bryan Huntsman <bryanh(a)codeaurora.org>
Cc: Daniel Walker <dwalker(a)fifo99.com>
Cc: David Brown <davidb(a)codeaurora.org>
Cc: Stephen Warren <swarren(a)wwwdotorg.org>
Cc: Tobias Klauser <tklauser(a)distanz.ch>
Cc: Tony Prisk <linux(a)prisktech.co.nz>
Viresh Kumar (25):
tty: serial: altera_jtag: drop uart_port->lock before calling
tty_flip_buffer_push()
tty: serial: altera: drop uart_port->lock before calling
tty_flip_buffer_push()
tty: serial: apbuart: drop uart_port->lock before calling
tty_flip_buffer_push()
tty: serial: ar933x: drop uart_port->lock before calling
tty_flip_buffer_push()
tty: serial: arc: drop uart_port->lock before calling
tty_flip_buffer_push()
tty: serial: bcm63xx: drop uart_port->lock before calling
tty_flip_buffer_push()
tty: serial: bfin_sport: drop uart_port->lock before calling
tty_flip_buffer_push()
tty: serial: efm32: drop uart_port->lock before calling
tty_flip_buffer_push()
tty: serial: icom: drop uart_port->lock before calling
tty_flip_buffer_push()
tty: serial: lpc32xx_hs: don't call tty_flip_buffer_push() twice
tty: serial: lpc32xx_hs: drop uart_port->lock before calling
tty_flip_buffer_push()
tty: serial: m32r_sio: drop uart_port->lock before calling
tty_flip_buffer_push()
tty: serial: mcf: drop uart_port->lock before calling
tty_flip_buffer_push()
tty: serial: mfd: drop uart_port->lock before calling
tty_flip_buffer_push()
tty: serial: mpsc: drop uart_port->lock before calling
tty_flip_buffer_push()
tty: serial: msm: drop uart_port->lock before calling
tty_flip_buffer_push()
tty: serial: netx: drop uart_port->lock before calling
tty_flip_buffer_push()
tty: serial: nwpserial: drop uart_port->lock before calling
tty_flip_buffer_push()
tty: serial: pnx8xxx: drop uart_port->lock before calling
tty_flip_buffer_push()
tty: serial: rp2: drop uart_port->lock before calling
tty_flip_buffer_push()
tty: serial: sa1100: drop uart_port->lock before calling
tty_flip_buffer_push()
tty: serial: samsung: drop uart_port->lock before calling
tty_flip_buffer_push()
tty: serial: tegra: drop uart_port->lock before calling
tty_flip_buffer_push()
tty: serial: sirfsoc: drop uart_port->lock before calling
tty_flip_buffer_push()
tty: serial: vt8500: drop uart_port->lock before calling
tty_flip_buffer_push()
drivers/tty/serial/altera_jtaguart.c | 2 ++
drivers/tty/serial/altera_uart.c | 2 ++
drivers/tty/serial/apbuart.c | 2 ++
drivers/tty/serial/ar933x_uart.c | 2 ++
drivers/tty/serial/arc_uart.c | 2 ++
drivers/tty/serial/bcm63xx_uart.c | 2 ++
drivers/tty/serial/bfin_sport_uart.c | 5 +++--
drivers/tty/serial/efm32-uart.c | 4 ++--
drivers/tty/serial/icom.c | 3 +++
drivers/tty/serial/lpc32xx_hs.c | 7 ++++---
drivers/tty/serial/m32r_sio.c | 3 +++
drivers/tty/serial/mcf.c | 2 ++
drivers/tty/serial/mfd.c | 14 ++++++++++----
drivers/tty/serial/mpsc.c | 11 ++++++++---
drivers/tty/serial/msm_serial.c | 5 +++++
drivers/tty/serial/netx-serial.c | 6 ++++--
drivers/tty/serial/nwpserial.c | 3 +++
drivers/tty/serial/pnx8xxx_uart.c | 3 +++
drivers/tty/serial/rp2.c | 2 ++
drivers/tty/serial/sa1100.c | 3 +++
drivers/tty/serial/samsung.c | 5 ++++-
drivers/tty/serial/serial-tegra.c | 10 ++++++++--
drivers/tty/serial/sirfsoc_uart.c | 3 +++
drivers/tty/serial/vt8500_serial.c | 2 ++
24 files changed, 84 insertions(+), 19 deletions(-)
--
1.7.12.rc2.18.g61b472e
Hi Rafael,
I am almost done with cleanup of drivers and am back at cpufreq core.. :)
I got to this structure: struct cpufreq_real_policy;
And I am not able to understand what's the need for this structure?
Can you let me know? Before I try to get rid of it :)
--
viresh
This patch adds a Kconfig dependency on an ARCH_VEXPRESS(it is for
both ARM and ARM64) or ARCH_VEXPRESS_CA9X being available before
VEXPRESS_CONFIG can be enabled. Without this patch,build system
can lead to issues. This was discovered during randconfig testing,
in which VEXPRESS_CONFIG was enabled w/o ARCH_VEXPRESS or VEXPRESS_CONFIG
being enabled,leading to the following error:
CC drivers/mfd/vexpress-config.o
drivers/mfd/vexpress-config.c: In function ‘__vexpress_config_func_get’:
drivers/mfd/vexpress-config.c:117:4: error: implicit declaration of function
‘of_find_node_by_phandle’ [-Werror=implicit-function-declaration]
bridge_node = of_find_node_by_phandle(
^
drivers/mfd/vexpress-config.c:117:16: warning: assignment makes pointer from
integer without a cast [enabled by default]
bridge_node = of_find_node_by_phandle(
Signed-off-by: Manjunath Goudar <manjunath.goudar(a)linaro.org>
Cc: Arnd Bergmann <arnd(a)arndb.de>
Cc: Deepak Saxena <dsaxena(a)linaro.org>
Cc: Samuel Ortiz <sameo(a)linux.intel.com>
Cc: Lee Jones <lee.jones(a)linaro.org>
---
drivers/mfd/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 633ee43..c9202f6 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -1174,7 +1174,7 @@ endmenu
config VEXPRESS_CONFIG
bool "ARM Versatile Express platform infrastructure"
- depends on ARM || ARM64
+ depends on ARCH_VEXPRESS || ARCH_VEXPRESS_CA9X4
help
Platform configuration infrastructure for the ARM Ltd.
Versatile Express.
--
1.7.9.5
From: root <root(a)si-cspbld63.lge.net>
This patch adds a omap1510_fpga_init_irq() inline dummy implementations
in arch/arm/mach-omap1/common.h. Without this patch,build system can
lead to issues. This was discovered during randconfig testing,in which
other than CONFIG_ARCH_OMAP15XX was enabled the leading to the following
error:
CC arch/arm/mach-omap1/board-innovator.o
arch/arm/mach-omap1/board-innovator.c: In function ‘innovator_init’:
arch/arm/mach-omap1/board-innovator.c:377:3: error: implicit declaration of
function ‘omap1510_fpga_init_irq’ [-Werror=implicit-function-declaration]
cc1: some warnings being treated as errors
make[1]: *** [arch/arm/mach-omap1/board-innovator.o] Error 1
make: *** [arch/arm/mach-omap1] Error 2
Signed-off-by: Manjunath Goudar <manjunath.goudar(a)linaro.org>
Cc: Arnd Bergmann <arnd(a)arndb.de>
Cc: Deepak Saxena <dsaxena(a)linaro.org>
Cc: Linus Walleij <linus.walleij(a)linaro.org>
Cc: Tony Lindgren <tony(a)atomide.com>
Cc: linux-omap(a)vger.kernel.org
---
arch/arm/mach-omap1/common.h | 3 +++
1 file changed, 3 insertions(+)
diff --git a/arch/arm/mach-omap1/common.h b/arch/arm/mach-omap1/common.h
index abec019..732f8ee 100644
--- a/arch/arm/mach-omap1/common.h
+++ b/arch/arm/mach-omap1/common.h
@@ -46,6 +46,9 @@ static inline void omap7xx_map_io(void)
void omap1510_fpga_init_irq(void);
void omap15xx_map_io(void);
#else
+static inline void omap1510_fpga_init_irq(void)
+{
+}
static inline void omap15xx_map_io(void)
{
}
--
1.8.1.2
Hi Rafael,
Hopefully this is the last patch for 3.12 for ARM CPUFreq subsystem.
The following changes since commit b36f4be3de1b123d8601de062e7dbfc904f305fb:
Linux 3.11-rc6 (2013-08-18 14:36:53 -0700)
are available in the git repository at:
git://git.linaro.org/people/vireshk/linux.git cpufreq-fixes
for you to fetch changes up to b192b910f3832793082c1a18262c4da0efe121ae:
cpufreq: tegra: fix the wrong clock name (2013-08-23 21:58:28 +0530)
----------------------------------------------------------------
Joseph Lo (1):
cpufreq: tegra: fix the wrong clock name
drivers/cpufreq/tegra-cpufreq.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
Hi Tommi,
I am looking for info and help on the libunwind API.
What I am trying to achieve is to allow the callchain feature on perf for
ARM (v7 to start with, then ARMv8), from the DWARF info found in the
.debug_frame section.
>From the source code in tools/perf I have added the call to
dwarf_find_debug_frame to load and parse the debug info from .debug_frame.
This works correctly, all IP ranges are found from the debug code (test
program and libraries). Then at some point I get an assertion: 'perf:
dwarf/Gparser.c:459: fetch_proc_info: Assertion `c->pi.unwind_info'
failed.' At that point c->pi is NULL. Cf. below for more info.
It looks like I am not using the libunwind API as it should, so that the
perf code apparently builds a list of IP ranges to resolve but cannot use
it later on to gather statistics on the runtime info.
Any idea on how to progress? I am also looking at the *_proc_info API of
libunwind.
Here is the patch I am using below.
Regards,
Jean
---
Log:
_Uarm_step: calling dwarf_step(ip=0x8464, c->dwarf@0xbee150f8,
c->dwarf.pi@0xb2bc0008)
unwind: find_proc_info dso /home/linaro/perf-libunwind/test_app/stress_bt
read_unwind_spec_debug_frame: .debug_frame offset=9304
opened file '/home/linaro/perf-libunwind/test_app/stress_bt'. Section
header at offset 18152
read 3160 bytes of .debug_frame from offset 9304
...
_ULarm_step: calling dwarf_step(ip=0xb6e6e764, c->dwarf@0xbee07508,
c->dwarf.pi@0xb6e955c0)
_ULarm_find_proc_info: looking for IP=0xb6e6e763
opened file '/usr/lib/arm-linux-gnueabihf/libunwind.so.8'. Section header
at offset 513260
read 17072 bytes of .debug_frame from offset 451836
_ULarm_dwarf_search_unwind_table: looking for IP=0xb6e6e763
_ULarm_find_proc_info returns 0
...
perf: dwarf/Gparser.c:459: fetch_proc_info: Assertion `c->pi.unwind_info'
failed.
---
Patch to the kernel source:
diff --git a/tools/perf/util/unwind.c b/tools/perf/util/unwind.c
index 958723b..dd97688 100644
--- a/tools/perf/util/unwind.c
+++ b/tools/perf/util/unwind.c
@@ -39,6 +39,14 @@ UNW_OBJ(dwarf_search_unwind_table) (unw_addr_space_t as,
#define dwarf_search_unwind_table UNW_OBJ(dwarf_search_unwind_table)
+extern int
+UNW_OBJ(dwarf_find_debug_frame) (int found, unw_dyn_info_t *di_debug,
+ unw_word_t ip, unw_word_t segbase,
+ const char* obj_name, unw_word_t start,
+ unw_word_t end);
+
+#define dwarf_find_debug_frame UNW_OBJ(dwarf_find_debug_frame)
+
#define DW_EH_PE_FORMAT_MASK 0x0f /* format of the encoded value */
#define DW_EH_PE_APPL_MASK 0x70 /* how the value is to be applied */
@@ -245,8 +253,9 @@ static int unwind_spec_ehframe(struct dso *dso,
struct machine *machine,
return 0;
}
-static int read_unwind_spec(struct dso *dso, struct machine *machine,
- u64 *table_data, u64 *segbase, u64 *fde_count)
+static int read_unwind_spec_eh_frame(struct dso *dso, struct machine
*machine,
+ u64 *table_data, u64 *segbase,
+ u64 *fde_count)
{
int ret = -EINVAL, fd;
u64 offset;
@@ -255,18 +264,40 @@ static int read_unwind_spec(struct dso *dso,
struct machine *machine,
if (fd < 0)
return -EINVAL;
+ /* Check the .eh_frame section for unwinding info */
offset = elf_section_offset(fd, ".eh_frame_hdr");
close(fd);
- if (offset)
+ if (offset) {
+ fprintf(stderr, "%s: .eh_frame offset=%llu\n", __func__, offset);
ret = unwind_spec_ehframe(dso, machine, offset,
table_data, segbase,
fde_count);
+ }
- /* TODO .debug_frame check if eh_frame_hdr fails */
return ret;
}
+static int read_unwind_spec_debug_frame(struct dso *dso,
+ struct machine *machine,
+ u64 *segbase)
+{
+ int fd = dso__data_fd(dso, machine);
+ if (fd < 0)
+ return -EINVAL;
+
+ /* Check the .debug_frame section for unwinding info */
+ *segbase = elf_section_offset(fd, ".debug_frame");
+ close(fd);
+
+ fprintf(stderr, "%s: .debug_frame offset=%llu\n", __func__, *segbase);
+
+ if (!segbase)
+ return -EINVAL;
+
+ return 0;
+}
+
static struct map *find_map(unw_word_t ip, struct unwind_info *ui)
{
struct addr_location al;
@@ -289,22 +320,32 @@ find_proc_info(unw_addr_space_t as, unw_word_t
ip, unw_proc_info_t *pi,
if (!map || !map->dso)
return -EINVAL;
- pr_debug("unwind: find_proc_info dso %s\n", map->dso->name);
+ fprintf(stderr, "unwind: find_proc_info dso %s\n", map->dso->name);
+
+ /* Check the .eh_frame section for unwinding info */
+ if (!read_unwind_spec_eh_frame(map->dso, ui->machine,
+ &table_data, &segbase, &fde_count)) {
+ memset(&di, 0, sizeof(di));
+ di.format = UNW_INFO_FORMAT_REMOTE_TABLE;
+ di.start_ip = map->start;
+ di.end_ip = map->end;
+ di.u.rti.segbase = map->start + segbase;
+ di.u.rti.table_data = map->start + table_data;
+ di.u.rti.table_len = fde_count * sizeof(struct table_entry)
+ / sizeof(unw_word_t);
+ return dwarf_search_unwind_table(as, ip, &di, pi,
+ need_unwind_info, arg);
+ }
- if (read_unwind_spec(map->dso, ui->machine,
- &table_data, &segbase, &fde_count))
- return -EINVAL;
+ /* Check the .debug_frame section for unwinding info */
+ if (!read_unwind_spec_debug_frame(map->dso, ui->machine, &segbase)) {
+ memset(&di, 0, sizeof(di));
+ if (dwarf_find_debug_frame(0, &di, ip, segbase, map->dso->name,
+ map->start, map->end))
+ return 0;
+ }
- memset(&di, 0, sizeof(di));
- di.format = UNW_INFO_FORMAT_REMOTE_TABLE;
- di.start_ip = map->start;
- di.end_ip = map->end;
- di.u.rti.segbase = map->start + segbase;
- di.u.rti.table_data = map->start + table_data;
- di.u.rti.table_len = fde_count * sizeof(struct table_entry)
- / sizeof(unw_word_t);
- return dwarf_search_unwind_table(as, ip, &di, pi,
- need_unwind_info, arg);
+ return -EINVAL;
}
static int access_fpreg(unw_addr_space_t __maybe_unused as,
This patchset does the following 3 things:
1) Fixes the RTC DT node name for Exynos5250
2) Update the "status" property of RTC DT node for Exynos5250 SoC
3) Adds RTC DT node to Exynos5420 SoC
changes since v5:
- Fixed the RTC DT node name for Exynos5250 board files also,
because otherwise it breaks RTC support in bisections.
changes since v4:
- removed "status" property of RTC DT node from exynos5250 board dts files
changes since v3:
- split the 5250 related modifications into 2 separate patch as
suggested by Tomasz Figa <t.figa(a)samsung.com>
changes since v2:
- split the 5250 related modifications into a separate patch.
- placed the RTC node as per the alphabetical order in the DTS file as
suggested by Kukjin Kim <kgene(a)kernel.org>.
changes since v1:
- made DT node status as "okay" in the dtsi file itself.
Vikas Sajjan (3):
ARM: dts: Fix the RTC DT node name for Exynos5250
ARM: dts: Update the "status" property of RTC DT node for Exynos5250
SoC
ARM: dts: Add RTC DT node to Exynos5420 SoC
arch/arm/boot/dts/exynos5.dtsi | 2 +-
arch/arm/boot/dts/exynos5250-arndale.dts | 4 ----
arch/arm/boot/dts/exynos5250-snow.dts | 4 ----
arch/arm/boot/dts/exynos5250.dtsi | 3 ++-
arch/arm/boot/dts/exynos5420.dtsi | 6 ++++++
5 files changed, 9 insertions(+), 10 deletions(-)
--
1.7.9.5
The Versatile Express TC2 board, which we use as our main emulated
platform in QEMU, defines 160+32 == 192 interrupts, so limiting the
number of interrupts to 128 is not quite going to cut it for real board
emulation.
Note that this didn't use to be a problem because QEMU was buggy and
only defined 128 interrupts until recently.
[ Sending this as an RFC, because I haven't convinced myself that
this is even the right short-term fix. On a longer-term we probably
need a way for QEMU to tell the kernel how many IRQs it needs for a
particular implementation of a CPU and a GIC, but on a shorter term
we should at least support a real A15 configuration. Note that this
change increases the in-kernel memory consumption quite a bit,
especially due to the irq-to-lr map, which could be reversed or
turned into a hash table or list, at the sacrifice of some
performance during world-switches to search the data structure. ]
Signed-off-by: Christoffer Dall <christoffer.dall(a)linaro.org>
---
include/kvm/arm_vgic.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index 343744e..7e2d158 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -26,7 +26,7 @@
#include <linux/types.h>
#include <linux/irqchip/arm-gic.h>
-#define VGIC_NR_IRQS 128
+#define VGIC_NR_IRQS 256
#define VGIC_NR_SGIS 16
#define VGIC_NR_PPIS 16
#define VGIC_NR_PRIVATE_IRQS (VGIC_NR_SGIS + VGIC_NR_PPIS)
--
1.7.10.4