aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2008-03-04 17:29:30 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2008-03-04 19:35:17 -0500
commit8311c29d40235062a843f4a8e8a70a44af6fe4c9 (patch)
treec869143fae8f135646300d1bac6639af5bb30dd7
parenta35e63efa1fb18c6f20f38e3ddf3f8ffbcf0f6e7 (diff)
md: reduce CPU wastage on idle md array with a write-intent bitmap
On an md array with a write-intent bitmap, a thread wakes up every few seconds and scans the bitmap looking for work to do. If the array is idle, there will be no work to do, but a lot of scanning is done to discover this. So cache the fact that the bitmap is completely clean, and avoid scanning the whole bitmap when the cache is known to be clean. Signed-off-by: Neil Brown <neilb@suse.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--drivers/md/bitmap.c19
-rw-r--r--include/linux/raid/bitmap.h2
2 files changed, 19 insertions, 2 deletions
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index 7aeceedcf7d4..831aed9c56ff 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -1047,6 +1047,11 @@ void bitmap_daemon_work(struct bitmap *bitmap)
1047 if (time_before(jiffies, bitmap->daemon_lastrun + bitmap->daemon_sleep*HZ)) 1047 if (time_before(jiffies, bitmap->daemon_lastrun + bitmap->daemon_sleep*HZ))
1048 return; 1048 return;
1049 bitmap->daemon_lastrun = jiffies; 1049 bitmap->daemon_lastrun = jiffies;
1050 if (bitmap->allclean) {
1051 bitmap->mddev->thread->timeout = MAX_SCHEDULE_TIMEOUT;
1052 return;
1053 }
1054 bitmap->allclean = 1;
1050 1055
1051 for (j = 0; j < bitmap->chunks; j++) { 1056 for (j = 0; j < bitmap->chunks; j++) {
1052 bitmap_counter_t *bmc; 1057 bitmap_counter_t *bmc;
@@ -1068,8 +1073,10 @@ void bitmap_daemon_work(struct bitmap *bitmap)
1068 clear_page_attr(bitmap, page, BITMAP_PAGE_NEEDWRITE); 1073 clear_page_attr(bitmap, page, BITMAP_PAGE_NEEDWRITE);
1069 1074
1070 spin_unlock_irqrestore(&bitmap->lock, flags); 1075 spin_unlock_irqrestore(&bitmap->lock, flags);
1071 if (need_write) 1076 if (need_write) {
1072 write_page(bitmap, page, 0); 1077 write_page(bitmap, page, 0);
1078 bitmap->allclean = 0;
1079 }
1073 continue; 1080 continue;
1074 } 1081 }
1075 1082
@@ -1098,6 +1105,9 @@ void bitmap_daemon_work(struct bitmap *bitmap)
1098/* 1105/*
1099 if (j < 100) printk("bitmap: j=%lu, *bmc = 0x%x\n", j, *bmc); 1106 if (j < 100) printk("bitmap: j=%lu, *bmc = 0x%x\n", j, *bmc);
1100*/ 1107*/
1108 if (*bmc)
1109 bitmap->allclean = 0;
1110
1101 if (*bmc == 2) { 1111 if (*bmc == 2) {
1102 *bmc=1; /* maybe clear the bit next time */ 1112 *bmc=1; /* maybe clear the bit next time */
1103 set_page_attr(bitmap, page, BITMAP_PAGE_CLEAN); 1113 set_page_attr(bitmap, page, BITMAP_PAGE_CLEAN);
@@ -1132,6 +1142,8 @@ void bitmap_daemon_work(struct bitmap *bitmap)
1132 } 1142 }
1133 } 1143 }
1134 1144
1145 if (bitmap->allclean == 0)
1146 bitmap->mddev->thread->timeout = bitmap->daemon_sleep * HZ;
1135} 1147}
1136 1148
1137static bitmap_counter_t *bitmap_get_counter(struct bitmap *bitmap, 1149static bitmap_counter_t *bitmap_get_counter(struct bitmap *bitmap,
@@ -1226,6 +1238,7 @@ int bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long sect
1226 sectors -= blocks; 1238 sectors -= blocks;
1227 else sectors = 0; 1239 else sectors = 0;
1228 } 1240 }
1241 bitmap->allclean = 0;
1229 return 0; 1242 return 0;
1230} 1243}
1231 1244
@@ -1296,6 +1309,7 @@ int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks,
1296 } 1309 }
1297 } 1310 }
1298 spin_unlock_irq(&bitmap->lock); 1311 spin_unlock_irq(&bitmap->lock);
1312 bitmap->allclean = 0;
1299 return rv; 1313 return rv;
1300} 1314}
1301 1315
@@ -1332,6 +1346,7 @@ void bitmap_end_sync(struct bitmap *bitmap, sector_t offset, int *blocks, int ab
1332 } 1346 }
1333 unlock: 1347 unlock:
1334 spin_unlock_irqrestore(&bitmap->lock, flags); 1348 spin_unlock_irqrestore(&bitmap->lock, flags);
1349 bitmap->allclean = 0;
1335} 1350}
1336 1351
1337void bitmap_close_sync(struct bitmap *bitmap) 1352void bitmap_close_sync(struct bitmap *bitmap)
@@ -1399,7 +1414,7 @@ static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, int n
1399 set_page_attr(bitmap, page, BITMAP_PAGE_CLEAN); 1414 set_page_attr(bitmap, page, BITMAP_PAGE_CLEAN);
1400 } 1415 }
1401 spin_unlock_irq(&bitmap->lock); 1416 spin_unlock_irq(&bitmap->lock);
1402 1417 bitmap->allclean = 0;
1403} 1418}
1404 1419
1405/* dirty the memory and file bits for bitmap chunks "s" to "e" */ 1420/* dirty the memory and file bits for bitmap chunks "s" to "e" */
diff --git a/include/linux/raid/bitmap.h b/include/linux/raid/bitmap.h
index e51b531cd0b2..47fbcba11850 100644
--- a/include/linux/raid/bitmap.h
+++ b/include/linux/raid/bitmap.h
@@ -235,6 +235,8 @@ struct bitmap {
235 235
236 unsigned long flags; 236 unsigned long flags;
237 237
238 int allclean;
239
238 unsigned long max_write_behind; /* write-behind mode */ 240 unsigned long max_write_behind; /* write-behind mode */
239 atomic_t behind_writes; 241 atomic_t behind_writes;
240 242