lkml.org 
[lkml]   [2008]   [Jun]   [24]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[PATCH 1/2] Avoid bio_endio recursion
Hi

bio_endio calls bi_end_io callback. In case of stacked devices (raid, dm),
bio_end_io may call bio_endio again, up to an unspecified length.

The crash because of stack overflow was really observed on sparc64. And
this recursion was one of the contributing factors (using 9 stack frames
--- that is 1728 bytes).

This patch removes the recursion.

Mikulas

--

Avoid recursion on bio_endio. bio_endio calls bio->bi_end_io which may in turn
call bio_endio again. When this recursion happens, put the new bio to the queue
and process it later, from the top-level bio_endio.

Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>

Index: linux-2.6.26-rc5-devel/fs/bio.c
===================================================================
--- linux-2.6.26-rc5-devel.orig/fs/bio.c 2008-06-18 23:48:45.000000000 +0200
+++ linux-2.6.26-rc5-devel/fs/bio.c 2008-06-19 00:15:56.000000000 +0200
@@ -1168,6 +1168,27 @@
**/
void bio_endio(struct bio *bio, int error)
{
+ static DEFINE_PER_CPU(struct bio **, bio_end_queue) = { NULL };
+ struct bio ***bio_end_queue_ptr;
+ struct bio *bio_queue;
+
+ unsigned long flags;
+
+ local_irq_save(flags);
+ bio_end_queue_ptr = &__get_cpu_var(bio_end_queue);
+
+ if (*bio_end_queue_ptr) {
+ **bio_end_queue_ptr = bio;
+ *bio_end_queue_ptr = &bio->bi_next;
+ bio->bi_next = NULL;
+ goto ret;
+ }
+
+ bio_queue = NULL;
+queue_empty_next_bio:
+ *bio_end_queue_ptr = &bio_queue;
+next_bio:
+
if (error)
clear_bit(BIO_UPTODATE, &bio->bi_flags);
else if (!test_bit(BIO_UPTODATE, &bio->bi_flags))
@@ -1175,6 +1196,17 @@

if (bio->bi_end_io)
bio->bi_end_io(bio, error);
+
+ if (bio_queue) {
+ bio = bio_queue;
+ bio_queue = bio->bi_next;
+ if (!bio_queue) goto queue_empty_next_bio;
+ goto next_bio;
+ }
+ *bio_end_queue_ptr = NULL;
+
+ret:
+ local_irq_restore(flags);
}

void bio_pair_release(struct bio_pair *bp)

\
 
 \ /
  Last update: 2008-06-24 07:25    [W:0.510 / U:0.016 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site