mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [10 PATCHES] inline functions to avoid stack overflow
@ 2008-06-24  5:54 Mikulas Patocka
  2008-06-24  5:55 ` [1/10 PATCH] inline __queue_work Mikulas Patocka
                   ` (3 more replies)
  0 siblings, 4 replies; 34+ messages in thread
From: Mikulas Patocka @ 2008-06-24  5:54 UTC (permalink / raw)
  To: linux-kernel, sparclinux; +Cc: davem

Hi

Here I'm sending 10 patches to inline various functions.

To give you some understanding of sparc64, every function there uses big 
stack frame (at least 192 bytes). 128 bytes are required by architecture 
(16 64-bit registers), 48 bytes are there due to mistake of Sparc64 ABI 
designers (calling function has to allocate 48 bytes for called function) 
and 16 bytes are some dubious padding.

So, on sparc64, if you have a simple function that passes arguments to 
other function it still takes 192 byte --- regardless of how simple the 
function is. Tail-call may be used, but it is disabled in kernel if 
debugging is enabled (Makefile: ifdef CONFIG_FRAME_POINTER
KBUILD_CFLAGS += -fno-omit-frame-pointer -fno-optimize-sibling-calls).

The stack trace has 75 nested functions, that totals to at least 14400 
bytes --- and it kills the 16k stack space on sparc. In the stack trace, 
there are many function which do nothing but pass parameters to other 
function. In this series of patches, I found 10 such functions and turned 
them to inlines, saving 1920 bytes. Especially waking wait queue is bad, 
it calls 8 nested functions, 7 of which do nothing. I turned 5 of them to 
inline.

I'll post those 10 patches in next emails.

Some of the patches fix cases that could be optimized with tail-calling. 
If you want to drop the patches, you should enable tail-calling by 
removing -fno-optimize-sibling-calls from Makefile (it makes debugging a 
bit harder).

This was the trace:

linux_sparc_syscall32
sys_read
vfs_read
do_sync_read
generic_file_aio_read
generic_file_direct_io
filemap_write_and_wait
filemap_fdatawrite
__filemap_fdatawrite_range
do_writepages
generic_writepages
write_cache_pages
__writepage
blkdev_writepage
block_write_full_page
__block_write_fiull_page
submit_bh
submit_bio
generic_make_request
dm_request
__split_bio
__map_bio
origin_map
start_copy
dm_kcopyd_copy
dispatch_job
wake
queue_work
__queue_work
__spin_unlock_irqrestore
sys_call_table
timer_interrupt
irq_exit
do_softirq
__do_softirq
run_timer_softirq
__spin_unlock_irq
sys_call_table
handler_irq
handler_fasteoi_irq
handle_irq_event
ide_intr
ide_dma_intr
task_end_request
ide_end_request
__ide_end_request
__blk_end_request
__end_that_request_first
req_bio_endio
bio_endio
clone_endio
dec_pending
bio_endio
clone_endio
dec_pending
bio_endio
clone_endio
dec_pending
bio_endio
end_bio_bh_io_sync
end_buffer_read_sync
__end_buffer_read_notouch
unlock_buffer
wake_up_bit
__wake_up_bit
__wake_up
__wake_up_common
wake_bio_function
autoremove_wake_function
default_wake_function
try_to_wake_up
task_rq_lock
__spin_lock
lock_acquire
__lock_acquire
*** crash ***

^ permalink raw reply	[flat|nested] 34+ messages in thread
* [PATCH] Limit irq nesting
@ 2008-07-17  1:42 Mikulas Patocka
  2008-07-17  1:57 ` KOSAKI Motohiro
  0 siblings, 1 reply; 34+ messages in thread
From: Mikulas Patocka @ 2008-07-17  1:42 UTC (permalink / raw)
  To: torvalds; +Cc: linux-kernel

Hi

During examination of stack-overflows on sparc64, it was found that there 
is no limit for a number of nested IRQ handlers. Sparc64 is especially 
stack-hungry architecture, minimum frame size is 192 bytes and after 75 
frames it overflows.

If someone provides a legitimate reason for more than 2 nested handlers, 
you could increase the constant in the patch --- but there really should 
be some limit, so that many simultaneous interrupts can't blow the stack.

Mikulas

---

IRQs without IRQF_DISABLED could nest to arbitrary level.

At worst this would mean having as many IRQ handlers stack frames, as there
are interrupts registered --- enough to cause a stack overflow.

This patch makes a limit to have at most two handlers on the stack.

Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
---
 include/linux/interrupt.h |    7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

Index: linux-2.6.26-rc8/include/linux/interrupt.h
===================================================================
--- linux-2.6.26-rc8.orig/include/linux/interrupt.h	2008-06-25 03:58:20.000000000 +0200
+++ linux-2.6.26-rc8/include/linux/interrupt.h	2008-07-01 17:42:44.000000000 +0200
@@ -16,6 +16,11 @@
 #include <asm/system.h>
 
 /*
+ * Max number of interrupt handlers on a stack. To prevent stack overflow.
+ */
+#define MAX_NESTED_INTERRUPTS	2
+
+/*
  * These correspond to the IORESOURCE_IRQ_* defines in
  * linux/ioport.h to select the interrupt line behaviour.  When
  * requesting an interrupt without specifying a IRQF_TRIGGER, the
@@ -95,7 +100,7 @@ extern void devm_free_irq(struct device 
 #ifdef CONFIG_LOCKDEP
 # define local_irq_enable_in_hardirq()	do { } while (0)
 #else
-# define local_irq_enable_in_hardirq()	local_irq_enable()
+# define local_irq_enable_in_hardirq()	do { if (hardirq_count() < (MAX_NESTED_INTERRUPTS << HARDIRQ_SHIFT)) local_irq_enable(); } while (0)
 #endif
 
 extern void disable_irq_nosync(unsigned int irq);

^ permalink raw reply	[flat|nested] 34+ messages in thread

end of thread, other threads:[~2008-07-17 11:59 UTC | newest]

Thread overview: 34+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-06-24  5:54 [10 PATCHES] inline functions to avoid stack overflow Mikulas Patocka
2008-06-24  5:55 ` [1/10 PATCH] inline __queue_work Mikulas Patocka
2008-06-24  5:56   ` [2/10 PATCH] inline inline-generic_writepages.patch Mikulas Patocka
2008-06-24  5:57   ` [3/10 PATCH] inline wake_up_bit Mikulas Patocka
2008-06-25 14:17     ` Denys Vlasenko
2008-06-25 14:36       ` Mikulas Patocka
2008-06-25 15:24         ` Denys Vlasenko
2008-06-25 16:01           ` Mikulas Patocka
2008-06-25 20:37             ` Denys Vlasenko
2008-06-26  0:28               ` David Miller
2008-06-26  3:35                 ` Denys Vlasenko
2008-06-26  4:18                   ` David Miller
2008-06-26 18:22                 ` Pavel Machek
2008-06-25 22:23           ` David Miller
2008-06-25 22:30       ` David Miller
2008-06-24  5:57   ` [4/10 PATCH] inline __wake_up_bit Mikulas Patocka
2008-06-24  5:58   ` [5/10 PATCH] inline __wake_up Mikulas Patocka
2008-06-24  5:59   ` [6/10 PATCH] inline default_wake_function Mikulas Patocka
2008-06-24  5:59   ` [6/10 PATCH] inline autoremove_wake_function Mikulas Patocka
2008-06-24  6:01   ` [8/10 PATCH] inline filemap_fdatawrite Mikulas Patocka
2008-06-24  6:01   ` [9/10 PATCH] inline dm-kcopyd-inline-wake.patch Mikulas Patocka
2008-06-24  6:03   ` [10/10 PATCH] inline dispatch_job Mikulas Patocka
2008-06-24  6:06 ` [PATCH] limit irq nesting Mikulas Patocka
2008-06-24  7:01 ` [10 PATCHES] inline functions to avoid stack overflow Ingo Molnar
     [not found] ` <486216E7.8000002@aitel.hist.no>
2008-06-25 12:53   ` Mikulas Patocka
2008-06-25 22:09     ` David Miller
2008-06-26  6:32       ` Bart Van Assche
2008-06-26  9:06         ` David Miller
2008-07-02  4:39       ` Mikulas Patocka
2008-07-02  4:45         ` David Miller
2008-07-03 21:12           ` Mikulas Patocka
2008-07-17  1:42 [PATCH] Limit irq nesting Mikulas Patocka
2008-07-17  1:57 ` KOSAKI Motohiro
2008-07-17 11:59   ` Mikulas Patocka

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

Powered by JetHome