[PATCH 1/2] Avoid bio_endio recursion

From: Mikulas Patocka
Date: Tue Jun 24 2008 - 01:22:52 EST


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@xxxxxxxxxx>

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)
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/