This patch adds prefetch function to dm-bufio. I'm adding Joe to CC,
because he may use it in his code too.
Mikulas
---
dm-bufio: prefetch
This patch introduces a new function dm_bufio_prefetch. It prefetches
the specified range of blocks into dm-bufio cache without waiting
for i/o completion.
+enum new_flag {
+ NF_FRESH = 0,
+ NF_READ = 1,
+ NF_GET = 2,
+ NF_PREFETCH = 3
+};
+
/*
* Allocate a new buffer. If the allocation is not possible, wait until
* some other thread frees a buffer.
*
* May drop the lock and regain it.
*/
-static struct dm_buffer *__alloc_buffer_wait_no_callback(struct dm_bufio_client *c)
+static struct dm_buffer *__alloc_buffer_wait_no_callback(struct dm_bufio_client *c, enum new_flag nf)
{
struct dm_buffer *b;
b = __find(c, block);
if (b) {
+found_buffer:
+ if (nf == NF_PREFETCH)
+ return NULL;
+ /*
+ * Note: it is essential that we don't wait for the buffer to be
+ * read if dm_bufio_get function is used. Both dm_bufio_get and
+ * dm_bufio_prefetch can be used in the driver request routine.
+ * If the user called both dm_bufio_prefetch and dm_bufio_get on
+ * the same buffer, it would deadlock if we waited.
+ */
+ if (nf == NF_GET && unlikely(test_bit(B_READING, &b->state)))
+ return NULL;
+
b->hold_count++;
__relink_lru(b, test_bit(B_DIRTY, &b->state) ||
test_bit(B_WRITING, &b->state));
@@ -891,7 +910,9 @@ static struct dm_buffer *__bufio_new(str
if (nf == NF_GET)
return NULL;
/*
* We've had a period where the mutex was unlocked, so need to
@@ -900,10 +921,7 @@ static struct dm_buffer *__bufio_new(str
b = __find(c, block);
if (b) {
__free_buffer_wake(new_b);
- b->hold_count++;
- __relink_lru(b, test_bit(B_DIRTY, &b->state) ||
- test_bit(B_WRITING, &b->state));
- return b;
+ goto found_buffer;
}
/*
+ * Prefetch the specified blocks to the cache.
+ * The function starts to read the blocks and returns without waiting for
+ * I/O to finish.
+ */
+void dm_bufio_prefetch(struct dm_bufio_client *c,
+ sector_t block, unsigned n_blocks);
+
+/*
* Release a reference obtained with dm_bufio_{read,get,new}. The data
* pointer and dm_buffer pointer is no longer valid after this call.
*/
--
dm-devel mailing list
dm-devel@redhat.com
https://www.redhat.com/mailman/listinfo/dm-devel
03-13-2012, 09:49 AM
Joe Thornber
dm-bufio: prefetch
On Mon, Mar 12, 2012 at 05:48:22PM -0400, Mikulas Patocka wrote:
> Hi
>
> This patch adds prefetch function to dm-bufio. I'm adding Joe to CC,
> because he may use it in his code too.
Yes, I can definitely use this.
Thanks,
- Joe
--
dm-devel mailing list
dm-devel@redhat.com
https://www.redhat.com/mailman/listinfo/dm-devel
03-13-2012, 12:00 PM
Mike Snitzer
dm-bufio: prefetch
On Mon, Mar 12 2012 at 5:48pm -0400,
Mikulas Patocka <mpatocka@redhat.com> wrote:
> Hi
>
> This patch adds prefetch function to dm-bufio. I'm adding Joe to CC,
> because he may use it in his code too.
>
> Mikulas
>
> ---
>
> dm-bufio: prefetch
>
> This patch introduces a new function dm_bufio_prefetch. It prefetches
> the specified range of blocks into dm-bufio cache without waiting
> for i/o completion.
>
> Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
>
> ---
> drivers/md/dm-bufio.c | 88 +++++++++++++++++++++++++++++++++++++++-----------
> drivers/md/dm-bufio.h | 8 ++++
> 2 files changed, 77 insertions(+), 19 deletions(-)
>
> Index: linux-3.3-rc6-fast/drivers/md/dm-bufio.c
> ================================================== =================
> --- linux-3.3-rc6-fast.orig/drivers/md/dm-bufio.c 2012-03-12 22:20:47.000000000 +0100
> +++ linux-3.3-rc6-fast/drivers/md/dm-bufio.c 2012-03-12 22:38:01.000000000 +0100
Shouldn't this be EXPORT_SYMBOL_GPL (to match other bufio exports)?
--
dm-devel mailing list
dm-devel@redhat.com
https://www.redhat.com/mailman/listinfo/dm-devel
03-13-2012, 01:46 PM
Mikulas Patocka
dm-bufio: prefetch
On Tue, 13 Mar 2012, Mike Snitzer wrote:
> > + dm_bufio_unlock(c);
> > + blk_finish_plug(&plug);
> > +}
> > +EXPORT_SYMBOL(dm_bufio_prefetch);
>
> Shouldn't this be EXPORT_SYMBOL_GPL (to match other bufio exports)?
Yes. Here is a new version.
---
dm-bufio: prefetch
This patch introduces a new function dm_bufio_prefetch. It prefetches
the specified range of blocks into dm-bufio cache without waiting
for i/o completion.
+enum new_flag {
+ NF_FRESH = 0,
+ NF_READ = 1,
+ NF_GET = 2,
+ NF_PREFETCH = 3
+};
+
/*
* Allocate a new buffer. If the allocation is not possible, wait until
* some other thread frees a buffer.
*
* May drop the lock and regain it.
*/
-static struct dm_buffer *__alloc_buffer_wait_no_callback(struct dm_bufio_client *c)
+static struct dm_buffer *__alloc_buffer_wait_no_callback(struct dm_bufio_client *c, enum new_flag nf)
{
struct dm_buffer *b;
b = __find(c, block);
if (b) {
+found_buffer:
+ if (nf == NF_PREFETCH)
+ return NULL;
+ /*
+ * Note: it is essential that we don't wait for the buffer to be
+ * read if dm_bufio_get function is used. Both dm_bufio_get and
+ * dm_bufio_prefetch can be used in the driver request routine.
+ * If the user called both dm_bufio_prefetch and dm_bufio_get on
+ * the same buffer, it would deadlock if we waited.
+ */
+ if (nf == NF_GET && unlikely(test_bit(B_READING, &b->state)))
+ return NULL;
+
b->hold_count++;
__relink_lru(b, test_bit(B_DIRTY, &b->state) ||
test_bit(B_WRITING, &b->state));
@@ -891,7 +910,9 @@ static struct dm_buffer *__bufio_new(str
if (nf == NF_GET)
return NULL;
/*
* We've had a period where the mutex was unlocked, so need to
@@ -900,10 +921,7 @@ static struct dm_buffer *__bufio_new(str
b = __find(c, block);
if (b) {
__free_buffer_wake(new_b);
- b->hold_count++;
- __relink_lru(b, test_bit(B_DIRTY, &b->state) ||
- test_bit(B_WRITING, &b->state));
- return b;
+ goto found_buffer;
}
/*
+ * Prefetch the specified blocks to the cache.
+ * The function starts to read the blocks and returns without waiting for
+ * I/O to finish.
+ */
+void dm_bufio_prefetch(struct dm_bufio_client *c,
+ sector_t block, unsigned n_blocks);
+
+/*
* Release a reference obtained with dm_bufio_{read,get,new}. The data
* pointer and dm_buffer pointer is no longer valid after this call.
*/
--
dm-devel mailing list
dm-devel@redhat.com
https://www.redhat.com/mailman/listinfo/dm-devel
03-13-2012, 10:04 PM
Alasdair G Kergon
dm-bufio: prefetch
Let's move this 'found_buffer' code after both places that use it, I think.
(goto an earlier point in the function would normally mean a loop, which
this isn't)
Alasdair
On Tue, Mar 13, 2012 at 10:46:00AM -0400, Mikulas Patocka wrote:
> @@ -882,6 +888,19 @@ static struct dm_buffer *__bufio_new(str
>
> b = __find(c, block);
> if (b) {
> +found_buffer:
> + if (nf == NF_PREFETCH)
> + return NULL;
> + /*
> + * Note: it is essential that we don't wait for the buffer to be
> + * read if dm_bufio_get function is used. Both dm_bufio_get and
> + * dm_bufio_prefetch can be used in the driver request routine.
> + * If the user called both dm_bufio_prefetch and dm_bufio_get on
> + * the same buffer, it would deadlock if we waited.
> + */
> + if (nf == NF_GET && unlikely(test_bit(B_READING, &b->state)))
> + return NULL;
> +
> b->hold_count++;
> __relink_lru(b, test_bit(B_DIRTY, &b->state) ||
> test_bit(B_WRITING, &b->state));