linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] ps3vram: Fix error path (return -EIO) for short read/write
@ 2009-04-03 13:05 Geert Uytterhoeven
  2009-04-03 13:05 ` [PATCH] ps3vram: Use proc_create_data() instead of proc_create() Geert Uytterhoeven
  0 siblings, 1 reply; 5+ messages in thread
From: Geert Uytterhoeven @ 2009-04-03 13:05 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Geert Uytterhoeven, linuxppc-dev, linux-kernel, cbe-oss-dev

Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
---
 drivers/block/ps3vram.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/block/ps3vram.c b/drivers/block/ps3vram.c
index 8eddef3..2e79d2c 100644
--- a/drivers/block/ps3vram.c
+++ b/drivers/block/ps3vram.c
@@ -585,6 +585,7 @@ static int ps3vram_make_request(struct request_queue *q, struct bio *bio)
 
 		if (retlen != len) {
 			dev_err(&dev->core, "Short %s\n", op);
+			error = -EIO;
 			goto out;
 		}
 
-- 
1.6.0.4

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

* [PATCH] ps3vram: Use proc_create_data() instead of proc_create()
  2009-04-03 13:05 [PATCH] ps3vram: Fix error path (return -EIO) for short read/write Geert Uytterhoeven
@ 2009-04-03 13:05 ` Geert Uytterhoeven
  2009-04-03 13:05   ` [PATCH] ps3vram: Correct exchanged gotos in ps3vram_probe() error path Geert Uytterhoeven
  0 siblings, 1 reply; 5+ messages in thread
From: Geert Uytterhoeven @ 2009-04-03 13:05 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Geert Uytterhoeven, linuxppc-dev, linux-kernel, cbe-oss-dev

Use proc_create_data() to avoid race conditions.

Reported-by: Alexey Dobriyan <adobriyan@gmail.com>
Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
---
 drivers/block/ps3vram.c |    8 +++-----
 1 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/block/ps3vram.c b/drivers/block/ps3vram.c
index 2e79d2c..6e73868 100644
--- a/drivers/block/ps3vram.c
+++ b/drivers/block/ps3vram.c
@@ -546,12 +546,10 @@ static void __devinit ps3vram_proc_init(struct ps3_system_bus_device *dev)
 	struct ps3vram_priv *priv = dev->core.driver_data;
 	struct proc_dir_entry *pde;
 
-	pde = proc_create(DEVICE_NAME, 0444, NULL, &ps3vram_proc_fops);
-	if (!pde) {
+	pde = proc_create_data(DEVICE_NAME, 0444, NULL, &ps3vram_proc_fops,
+			       priv);
+	if (!pde)
 		dev_warn(&dev->core, "failed to create /proc entry\n");
-		return;
-	}
-	pde->data = priv;
 }
 
 static int ps3vram_make_request(struct request_queue *q, struct bio *bio)
-- 
1.6.0.4

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

* [PATCH] ps3vram: Correct exchanged gotos in ps3vram_probe() error path
  2009-04-03 13:05 ` [PATCH] ps3vram: Use proc_create_data() instead of proc_create() Geert Uytterhoeven
@ 2009-04-03 13:05   ` Geert Uytterhoeven
  2009-04-03 13:05     ` [PATCH] ps3vram: Replace mutex by spinlock + list Geert Uytterhoeven
  0 siblings, 1 reply; 5+ messages in thread
From: Geert Uytterhoeven @ 2009-04-03 13:05 UTC (permalink / raw)
  To: Jens Axboe
  Cc: Geert Uytterhoeven, linuxppc-dev, linux-kernel, Jim Paris,
	cbe-oss-dev

From: Jim Paris <jim@jtan.com>

From: Jim Paris <jim@jtan.com>

Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
---
 drivers/block/ps3vram.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/block/ps3vram.c b/drivers/block/ps3vram.c
index 6e73868..3c9ad19 100644
--- a/drivers/block/ps3vram.c
+++ b/drivers/block/ps3vram.c
@@ -635,7 +635,7 @@ static int __devinit ps3vram_probe(struct ps3_system_bus_device *dev)
 	if (ps3_open_hv_device(dev)) {
 		dev_err(&dev->core, "ps3_open_hv_device failed\n");
 		error = -EAGAIN;
-		goto out_close_gpu;
+		goto out_free_xdr_buf;
 	}
 
 	/* Request memory */
@@ -659,7 +659,7 @@ static int __devinit ps3vram_probe(struct ps3_system_bus_device *dev)
 		dev_err(&dev->core, "lv1_gpu_memory_allocate failed %d\n",
 			status);
 		error = -ENOMEM;
-		goto out_free_xdr_buf;
+		goto out_close_gpu;
 	}
 
 	/* Request context */
-- 
1.6.0.4

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

* [PATCH] ps3vram: Replace mutex by spinlock + list
  2009-04-03 13:05   ` [PATCH] ps3vram: Correct exchanged gotos in ps3vram_probe() error path Geert Uytterhoeven
@ 2009-04-03 13:05     ` Geert Uytterhoeven
  2009-04-03 18:03       ` Jens Axboe
  0 siblings, 1 reply; 5+ messages in thread
From: Geert Uytterhoeven @ 2009-04-03 13:05 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Geert Uytterhoeven, linuxppc-dev, linux-kernel, cbe-oss-dev

Remove the mutex serializing access to the cache.
Instead, queue up new requests on a list if the driver is busy.

This improves sequential write performance by ca. 2%.

Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
---
 drivers/block/ps3vram.c |   55 ++++++++++++++++++++++++++++++++++------------
 1 files changed, 40 insertions(+), 15 deletions(-)

diff --git a/drivers/block/ps3vram.c b/drivers/block/ps3vram.c
index 3c9ad19..1396038 100644
--- a/drivers/block/ps3vram.c
+++ b/drivers/block/ps3vram.c
@@ -81,8 +81,8 @@ struct ps3vram_priv {
 
 	struct ps3vram_cache cache;
 
-	/* Used to serialize cache/DMA operations */
-	struct mutex lock;
+	spinlock_t lock;	/* protecting list of bios */
+	struct bio *tail;
 };
 
 
@@ -449,8 +449,6 @@ static int ps3vram_read(struct ps3_system_bus_device *dev, loff_t from,
 		offset = (unsigned int) (from & (priv->cache.page_size - 1));
 		avail  = priv->cache.page_size - offset;
 
-		mutex_lock(&priv->lock);
-
 		entry = ps3vram_cache_match(dev, from);
 		cached = CACHE_OFFSET + entry * priv->cache.page_size + offset;
 
@@ -462,8 +460,6 @@ static int ps3vram_read(struct ps3_system_bus_device *dev, loff_t from,
 			avail = count;
 		memcpy(buf, priv->xdr_buf + cached, avail);
 
-		mutex_unlock(&priv->lock);
-
 		buf += avail;
 		count -= avail;
 		from += avail;
@@ -494,8 +490,6 @@ static int ps3vram_write(struct ps3_system_bus_device *dev, loff_t to,
 		offset = (unsigned int) (to & (priv->cache.page_size - 1));
 		avail  = priv->cache.page_size - offset;
 
-		mutex_lock(&priv->lock);
-
 		entry = ps3vram_cache_match(dev, to);
 		cached = CACHE_OFFSET + entry * priv->cache.page_size + offset;
 
@@ -509,8 +503,6 @@ static int ps3vram_write(struct ps3_system_bus_device *dev, loff_t to,
 
 		priv->cache.tags[entry].flags |= CACHE_PAGE_DIRTY;
 
-		mutex_unlock(&priv->lock);
-
 		buf += avail;
 		count -= avail;
 		to += avail;
@@ -552,17 +544,17 @@ static void __devinit ps3vram_proc_init(struct ps3_system_bus_device *dev)
 		dev_warn(&dev->core, "failed to create /proc entry\n");
 }
 
-static int ps3vram_make_request(struct request_queue *q, struct bio *bio)
+static struct bio *ps3vram_do_bio(struct ps3_system_bus_device *dev,
+				  struct bio *bio)
 {
-	struct ps3_system_bus_device *dev = q->queuedata;
+	struct ps3vram_priv *priv = dev->core.driver_data;
 	int write = bio_data_dir(bio) == WRITE;
 	const char *op = write ? "write" : "read";
 	loff_t offset = bio->bi_sector << 9;
 	int error = 0;
 	struct bio_vec *bvec;
 	unsigned int i;
-
-	dev_dbg(&dev->core, "%s\n", __func__);
+	struct bio *next;
 
 	bio_for_each_segment(bvec, bio, i) {
 		/* PS3 is ppc64, so we don't handle highmem */
@@ -593,7 +585,40 @@ static int ps3vram_make_request(struct request_queue *q, struct bio *bio)
 	dev_dbg(&dev->core, "%s completed\n", op);
 
 out:
+	spin_lock_irq(&priv->lock);
+	next = bio->bi_next;
+	if (!next)
+		priv->tail = NULL;
+	else
+		bio->bi_next = NULL;
+	spin_unlock_irq(&priv->lock);
+
 	bio_endio(bio, error);
+	return next;
+}
+
+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->core.driver_data;
+
+	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;
+	spin_unlock_irq(&priv->lock);
+
+	do {
+		bio = ps3vram_do_bio(dev, bio);
+	} while (bio);
+
 	return 0;
 }
 
@@ -613,7 +638,7 @@ static int __devinit ps3vram_probe(struct ps3_system_bus_device *dev)
 		goto fail;
 	}
 
-	mutex_init(&priv->lock);
+	spin_lock_init(&priv->lock);
 	dev->core.driver_data = priv;
 
 	priv = dev->core.driver_data;
-- 
1.6.0.4

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

* Re: [PATCH] ps3vram: Replace mutex by spinlock + list
  2009-04-03 13:05     ` [PATCH] ps3vram: Replace mutex by spinlock + list Geert Uytterhoeven
@ 2009-04-03 18:03       ` Jens Axboe
  0 siblings, 0 replies; 5+ messages in thread
From: Jens Axboe @ 2009-04-03 18:03 UTC (permalink / raw)
  To: Geert Uytterhoeven; +Cc: linuxppc-dev, linux-kernel, cbe-oss-dev

On Fri, Apr 03 2009, Geert Uytterhoeven wrote:
> Remove the mutex serializing access to the cache.
> Instead, queue up new requests on a list if the driver is busy.
> 
> This improves sequential write performance by ca. 2%.

Great, precisely the method I wanted to see there! I've added your three
patches, thanks Geert.


-- 
Jens Axboe

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

end of thread, other threads:[~2009-04-03 18:03 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-04-03 13:05 [PATCH] ps3vram: Fix error path (return -EIO) for short read/write Geert Uytterhoeven
2009-04-03 13:05 ` [PATCH] ps3vram: Use proc_create_data() instead of proc_create() Geert Uytterhoeven
2009-04-03 13:05   ` [PATCH] ps3vram: Correct exchanged gotos in ps3vram_probe() error path Geert Uytterhoeven
2009-04-03 13:05     ` [PATCH] ps3vram: Replace mutex by spinlock + list Geert Uytterhoeven
2009-04-03 18:03       ` Jens Axboe

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).