Re: [Cbe-oss-dev] [PATCH 04/15] ps3vram: Replace mutex by spinlock + list
From: Geert Uytterhoeven <hidden>
Date: 2009-05-11 14:20:33
Also in:
lkml
Subsystem:
block layer, ps3 platform support, ps3vram driver, the rest · Maintainers:
Jens Axboe, Geoff Levand, Jim Paris, Linus Torvalds
On Sun, 10 May 2009, Christoph Hellwig wrote:
On Fri, May 08, 2009 at 04:01:13PM +0200, Geert Uytterhoeven wrote:quoted
Remove the mutex serializing access to the cache. Instead, queue up new requests on a list if the driver is busy.This should use the bio list helpers moved into bio.h in commit 8f3d8ba20e67991b531e9c0227dcd1f99271a32c
Ah, those didn't exist at the time of my previous submission ;-) Like this? Note that I had to introduce bio_list_peek(), as bio_list_pop() makes the list empty, and I cannot do that until the request has been processed. I'll split of the introduction of bio_list_peek() in a separate patch and will merge the rest in my earlier patches, if this is what you want.
diff --git a/drivers/block/ps3vram.c b/drivers/block/ps3vram.c
index abda565..aac51a2 100644
--- a/drivers/block/ps3vram.c
+++ b/drivers/block/ps3vram.c@@ -81,7 +81,7 @@ struct ps3vram_priv { struct ps3vram_cache cache; spinlock_t lock; /* protecting list of bios */ - struct bio *tail; + struct bio_list list; };
@@ -579,11 +579,8 @@ static struct bio *ps3vram_do_bio(struct ps3_system_bus_device *dev, out: spin_lock_irq(&priv->lock); - next = bio->bi_next; - if (!next) - priv->tail = NULL; - else - bio->bi_next = NULL; + bio_list_pop(&priv->list); + next = bio_list_peek(&priv->list); spin_unlock_irq(&priv->lock); bio_endio(bio, error);
@@ -594,20 +591,18 @@ static int ps3vram_make_request(struct request_queue *q, struct bio *bio) { struct ps3_system_bus_device *dev = q->queuedata; struct ps3vram_priv *priv = dev_get_drvdata(&dev->core); + int busy; dev_dbg(&dev->core, "%s\n", __func__); spin_lock_irq(&priv->lock); - if (priv->tail) { - priv->tail->bi_next = bio; - priv->tail = bio; - spin_unlock_irq(&priv->lock); - return 0; - } - - priv->tail = bio; + busy = !bio_list_empty(&priv->list); + bio_list_add(&priv->list, bio); spin_unlock_irq(&priv->lock); + if (busy) + return 0; + do { bio = ps3vram_do_bio(dev, bio); } while (bio);
@@ -632,6 +627,7 @@ static int __devinit ps3vram_probe(struct ps3_system_bus_device *dev) } spin_lock_init(&priv->lock); + bio_list_init(&priv->list); dev_set_drvdata(&dev->core, priv); /* Allocate XDR buffer (1MiB aligned) */
diff --git a/include/linux/bio.h b/include/linux/bio.h
index 7b214fd..618bb7d 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h@@ -590,6 +590,11 @@ static inline void bio_list_merge_head(struct bio_list *bl, bl->head = bl2->head; } +static inline struct bio *bio_list_peek(struct bio_list *bl) +{ + return bl->head; +} + static inline struct bio *bio_list_pop(struct bio_list *bl) { struct bio *bio = bl->head;
With kind regards, Geert Uytterhoeven Software Architect Techsoft Centre Technology and Software Centre Europe The Corporate Village � Da Vincilaan 7-D1 � B-1935 Zaventem � Belgium Phone: +32 (0)2 700 8453 Fax: +32 (0)2 700 8622 E-mail: Geert.Uytterhoeven@sonycom.com Internet: http://www.sony-europe.com/ A division of Sony Europe (Belgium) N.V. VAT BE 0413.825.160 � RPR Brussels Fortis � BIC GEBABEBB � IBAN BE41293037680010