[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[dm-devel] (no subject)



Hi

Here I'm sending two dm-bufio patches. The first one fixed 
dm_bufio_release_move function (the write callback could be called with a 
wrong block number). The next one adds a conditional resched (Alasdair 
agreed on it --- it should be later put into general Linux headers).

Mikulas
---
 drivers/md/dm-bufio.c |   13 +++++++++++++
 1 file changed, 13 insertions(+)

Index: linux-3.1-rc3-fast/drivers/md/dm-bufio.c
===================================================================
--- linux-3.1-rc3-fast.orig/drivers/md/dm-bufio.c	2011-10-19 18:39:22.000000000 +0200
+++ linux-3.1-rc3-fast/drivers/md/dm-bufio.c	2011-10-19 18:47:43.000000000 +0200
@@ -1185,11 +1185,24 @@ retry:
 		__unlink_buffer(b);
 		__link_buffer(b, new_block, LIST_DIRTY);
 	} else {
+		sector_t old_block;
 		wait_on_bit_lock(&b->state, B_WRITING,
 				 do_io_schedule, TASK_UNINTERRUPTIBLE);
+		/*
+		 * Relink buffer to "new_block" so that write_callback
+		 * sees "new_block" as a block number.
+		 * After the write, link the buffer back to old_block.
+		 * All this must be done in bufio lock, so that block number
+		 * change isn't visible to other threads.
+		 */
+		old_block = b->block;
+		__unlink_buffer(b);
+		__link_buffer(b, new_block, b->list_mode);
 		submit_io(b, WRITE, new_block, write_endio);
 		wait_on_bit(&b->state, B_WRITING,
 			    do_io_schedule, TASK_UNINTERRUPTIBLE);
+		__unlink_buffer(b);
+		__link_buffer(b, old_block, b->list_mode);
 	}
 
 	dm_bufio_unlock(c);
---
 drivers/md/dm-bufio.c |   26 ++++++++++++++++++++++++--
 1 file changed, 24 insertions(+), 2 deletions(-)

Index: linux-3.1-rc3-fast/drivers/md/dm-bufio.c
===================================================================
--- linux-3.1-rc3-fast.orig/drivers/md/dm-bufio.c	2011-10-19 18:49:14.000000000 +0200
+++ linux-3.1-rc3-fast/drivers/md/dm-bufio.c	2011-10-19 18:57:01.000000000 +0200
@@ -183,6 +183,16 @@ static void dm_bufio_unlock(struct dm_bu
 	mutex_unlock(&c->lock);
 }
 
+#ifdef CONFIG_PREEMPT_VOLUNTARY
+#define dm_bufio_cond_resched()                	\
+do {						\
+	if (unlikely(need_resched()))		\
+		_cond_resched();		\
+} while (0)
+#else
+#define dm_bufio_cond_resched()                do { } while (0)
+#endif
+
 /*----------------------------------------------------------------*/
 
 /*
@@ -644,6 +654,7 @@ static struct dm_buffer *__get_unclaimed
 			__unlink_buffer(b);
 			return b;
 		}
+		dm_bufio_cond_resched();
 	}
 
 	list_for_each_entry_reverse(b, &c->lru[LIST_DIRTY], lru_list) {
@@ -654,6 +665,7 @@ static struct dm_buffer *__get_unclaimed
 			__unlink_buffer(b);
 			return b;
 		}
+		dm_bufio_cond_resched();
 	}
 
 	return NULL;
@@ -772,6 +784,7 @@ static void __write_dirty_buffers_async(
 			return;
 
 		__write_dirty_buffer(b);
+		dm_bufio_cond_resched();
 	}
 }
 
@@ -820,6 +833,7 @@ static void __check_watermark(struct dm_
 			return;
 
 		__free_buffer_wake(b);
+		dm_bufio_cond_resched();
 	}
 
 	if (c->n_buffers[LIST_DIRTY] > threshold_buffers)
@@ -835,9 +849,11 @@ static struct dm_buffer *__find(struct d
 	struct hlist_node *hn;
 
 	hlist_for_each_entry(b, hn, &c->cache_hash[DM_BUFIO_HASH(block)],
-			     hash_list)
+			     hash_list) {
+		dm_bufio_cond_resched();
 		if (b->block == block)
 			return b;
+	}
 
 	return NULL;
 }
@@ -1084,6 +1100,8 @@ again:
 		    !test_bit(B_WRITING, &b->state))
 			__relink_lru(b, LIST_CLEAN);
 
+		dm_bufio_cond_resched();
+
 		/*
 		 * If we dropped the lock, the list is no longer consistent,
 		 * so we must restart the search.
@@ -1310,11 +1328,13 @@ static void __scan(struct dm_bufio_clien
 	int l;
 	struct dm_buffer *b, *tmp;
 
-	for (l = 0; l < LIST_SIZE; l++)
+	for (l = 0; l < LIST_SIZE; l++) {
 		list_for_each_entry_safe_reverse(b, tmp, &c->lru[l], lru_list)
 			if (!__cleanup_old_buffer(b, sc->gfp_mask, 0) &&
 			    !--nr_to_scan)
 				return;
+		dm_bufio_cond_resched();
+	}
 }
 
 static int shrink(struct shrinker *shrinker, struct shrink_control *sc)
@@ -1531,9 +1551,11 @@ static void cleanup_old_buffers(void)
 				       struct dm_buffer, lru_list);
 			if (__cleanup_old_buffer(b, 0, max_age * HZ))
 				break;
+			dm_bufio_cond_resched();
 		}
 
 		dm_bufio_unlock(c);
+		dm_bufio_cond_resched();
 	}
 	mutex_unlock(&dm_bufio_clients_lock);
 }

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]