aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/drbd/drbd_bitmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/block/drbd/drbd_bitmap.c')
-rw-r--r--drivers/block/drbd/drbd_bitmap.c34
1 files changed, 19 insertions, 15 deletions
diff --git a/drivers/block/drbd/drbd_bitmap.c b/drivers/block/drbd/drbd_bitmap.c
index f440a02dfdb1..1e89a74ddb17 100644
--- a/drivers/block/drbd/drbd_bitmap.c
+++ b/drivers/block/drbd/drbd_bitmap.c
@@ -112,9 +112,6 @@ struct drbd_bitmap {
112 struct task_struct *bm_task; 112 struct task_struct *bm_task;
113}; 113};
114 114
115static int __bm_change_bits_to(struct drbd_conf *mdev, const unsigned long s,
116 unsigned long e, int val, const enum km_type km);
117
118#define bm_print_lock_info(m) __bm_print_lock_info(m, __func__) 115#define bm_print_lock_info(m) __bm_print_lock_info(m, __func__)
119static void __bm_print_lock_info(struct drbd_conf *mdev, const char *func) 116static void __bm_print_lock_info(struct drbd_conf *mdev, const char *func)
120{ 117{
@@ -1256,7 +1253,7 @@ unsigned long _drbd_bm_find_next_zero(struct drbd_conf *mdev, unsigned long bm_f
1256 * expected to be called for only a few bits (e - s about BITS_PER_LONG). 1253 * expected to be called for only a few bits (e - s about BITS_PER_LONG).
1257 * Must hold bitmap lock already. */ 1254 * Must hold bitmap lock already. */
1258static int __bm_change_bits_to(struct drbd_conf *mdev, const unsigned long s, 1255static int __bm_change_bits_to(struct drbd_conf *mdev, const unsigned long s,
1259 unsigned long e, int val, const enum km_type km) 1256 unsigned long e, int val)
1260{ 1257{
1261 struct drbd_bitmap *b = mdev->bitmap; 1258 struct drbd_bitmap *b = mdev->bitmap;
1262 unsigned long *p_addr = NULL; 1259 unsigned long *p_addr = NULL;
@@ -1274,14 +1271,14 @@ static int __bm_change_bits_to(struct drbd_conf *mdev, const unsigned long s,
1274 unsigned int page_nr = bm_bit_to_page_idx(b, bitnr); 1271 unsigned int page_nr = bm_bit_to_page_idx(b, bitnr);
1275 if (page_nr != last_page_nr) { 1272 if (page_nr != last_page_nr) {
1276 if (p_addr) 1273 if (p_addr)
1277 __bm_unmap(p_addr, km); 1274 __bm_unmap(p_addr, KM_IRQ1);
1278 if (c < 0) 1275 if (c < 0)
1279 bm_set_page_lazy_writeout(b->bm_pages[last_page_nr]); 1276 bm_set_page_lazy_writeout(b->bm_pages[last_page_nr]);
1280 else if (c > 0) 1277 else if (c > 0)
1281 bm_set_page_need_writeout(b->bm_pages[last_page_nr]); 1278 bm_set_page_need_writeout(b->bm_pages[last_page_nr]);
1282 changed_total += c; 1279 changed_total += c;
1283 c = 0; 1280 c = 0;
1284 p_addr = __bm_map_pidx(b, page_nr, km); 1281 p_addr = __bm_map_pidx(b, page_nr, KM_IRQ1);
1285 last_page_nr = page_nr; 1282 last_page_nr = page_nr;
1286 } 1283 }
1287 if (val) 1284 if (val)
@@ -1290,7 +1287,7 @@ static int __bm_change_bits_to(struct drbd_conf *mdev, const unsigned long s,
1290 c -= (0 != __test_and_clear_bit_le(bitnr & BITS_PER_PAGE_MASK, p_addr)); 1287 c -= (0 != __test_and_clear_bit_le(bitnr & BITS_PER_PAGE_MASK, p_addr));
1291 } 1288 }
1292 if (p_addr) 1289 if (p_addr)
1293 __bm_unmap(p_addr, km); 1290 __bm_unmap(p_addr, KM_IRQ1);
1294 if (c < 0) 1291 if (c < 0)
1295 bm_set_page_lazy_writeout(b->bm_pages[last_page_nr]); 1292 bm_set_page_lazy_writeout(b->bm_pages[last_page_nr]);
1296 else if (c > 0) 1293 else if (c > 0)
@@ -1318,7 +1315,7 @@ static int bm_change_bits_to(struct drbd_conf *mdev, const unsigned long s,
1318 if ((val ? BM_DONT_SET : BM_DONT_CLEAR) & b->bm_flags) 1315 if ((val ? BM_DONT_SET : BM_DONT_CLEAR) & b->bm_flags)
1319 bm_print_lock_info(mdev); 1316 bm_print_lock_info(mdev);
1320 1317
1321 c = __bm_change_bits_to(mdev, s, e, val, KM_IRQ1); 1318 c = __bm_change_bits_to(mdev, s, e, val);
1322 1319
1323 spin_unlock_irqrestore(&b->bm_lock, flags); 1320 spin_unlock_irqrestore(&b->bm_lock, flags);
1324 return c; 1321 return c;
@@ -1343,16 +1340,17 @@ static inline void bm_set_full_words_within_one_page(struct drbd_bitmap *b,
1343{ 1340{
1344 int i; 1341 int i;
1345 int bits; 1342 int bits;
1346 unsigned long *paddr = kmap_atomic(b->bm_pages[page_nr], KM_USER0); 1343 unsigned long *paddr = kmap_atomic(b->bm_pages[page_nr], KM_IRQ1);
1347 for (i = first_word; i < last_word; i++) { 1344 for (i = first_word; i < last_word; i++) {
1348 bits = hweight_long(paddr[i]); 1345 bits = hweight_long(paddr[i]);
1349 paddr[i] = ~0UL; 1346 paddr[i] = ~0UL;
1350 b->bm_set += BITS_PER_LONG - bits; 1347 b->bm_set += BITS_PER_LONG - bits;
1351 } 1348 }
1352 kunmap_atomic(paddr, KM_USER0); 1349 kunmap_atomic(paddr, KM_IRQ1);
1353} 1350}
1354 1351
1355/* Same thing as drbd_bm_set_bits, but without taking the spin_lock_irqsave. 1352/* Same thing as drbd_bm_set_bits,
1353 * but more efficient for a large bit range.
1356 * You must first drbd_bm_lock(). 1354 * You must first drbd_bm_lock().
1357 * Can be called to set the whole bitmap in one go. 1355 * Can be called to set the whole bitmap in one go.
1358 * Sets bits from s to e _inclusive_. */ 1356 * Sets bits from s to e _inclusive_. */
@@ -1366,6 +1364,7 @@ void _drbd_bm_set_bits(struct drbd_conf *mdev, const unsigned long s, const unsi
1366 * Do not use memset, because we must account for changes, 1364 * Do not use memset, because we must account for changes,
1367 * so we need to loop over the words with hweight() anyways. 1365 * so we need to loop over the words with hweight() anyways.
1368 */ 1366 */
1367 struct drbd_bitmap *b = mdev->bitmap;
1369 unsigned long sl = ALIGN(s,BITS_PER_LONG); 1368 unsigned long sl = ALIGN(s,BITS_PER_LONG);
1370 unsigned long el = (e+1) & ~((unsigned long)BITS_PER_LONG-1); 1369 unsigned long el = (e+1) & ~((unsigned long)BITS_PER_LONG-1);
1371 int first_page; 1370 int first_page;
@@ -1376,15 +1375,19 @@ void _drbd_bm_set_bits(struct drbd_conf *mdev, const unsigned long s, const unsi
1376 1375
1377 if (e - s <= 3*BITS_PER_LONG) { 1376 if (e - s <= 3*BITS_PER_LONG) {
1378 /* don't bother; el and sl may even be wrong. */ 1377 /* don't bother; el and sl may even be wrong. */
1379 __bm_change_bits_to(mdev, s, e, 1, KM_USER0); 1378 spin_lock_irq(&b->bm_lock);
1379 __bm_change_bits_to(mdev, s, e, 1);
1380 spin_unlock_irq(&b->bm_lock);
1380 return; 1381 return;
1381 } 1382 }
1382 1383
1383 /* difference is large enough that we can trust sl and el */ 1384 /* difference is large enough that we can trust sl and el */
1384 1385
1386 spin_lock_irq(&b->bm_lock);
1387
1385 /* bits filling the current long */ 1388 /* bits filling the current long */
1386 if (sl) 1389 if (sl)
1387 __bm_change_bits_to(mdev, s, sl-1, 1, KM_USER0); 1390 __bm_change_bits_to(mdev, s, sl-1, 1);
1388 1391
1389 first_page = sl >> (3 + PAGE_SHIFT); 1392 first_page = sl >> (3 + PAGE_SHIFT);
1390 last_page = el >> (3 + PAGE_SHIFT); 1393 last_page = el >> (3 + PAGE_SHIFT);
@@ -1397,7 +1400,7 @@ void _drbd_bm_set_bits(struct drbd_conf *mdev, const unsigned long s, const unsi
1397 /* first and full pages, unless first page == last page */ 1400 /* first and full pages, unless first page == last page */
1398 for (page_nr = first_page; page_nr < last_page; page_nr++) { 1401 for (page_nr = first_page; page_nr < last_page; page_nr++) {
1399 bm_set_full_words_within_one_page(mdev->bitmap, page_nr, first_word, last_word); 1402 bm_set_full_words_within_one_page(mdev->bitmap, page_nr, first_word, last_word);
1400 cond_resched(); 1403 cond_resched_lock(&b->bm_lock);
1401 first_word = 0; 1404 first_word = 0;
1402 } 1405 }
1403 1406
@@ -1411,7 +1414,8 @@ void _drbd_bm_set_bits(struct drbd_conf *mdev, const unsigned long s, const unsi
1411 * it would trigger an assert in __bm_change_bits_to() 1414 * it would trigger an assert in __bm_change_bits_to()
1412 */ 1415 */
1413 if (el <= e) 1416 if (el <= e)
1414 __bm_change_bits_to(mdev, el, e, 1, KM_USER0); 1417 __bm_change_bits_to(mdev, el, e, 1);
1418 spin_unlock_irq(&b->bm_lock);
1415} 1419}
1416 1420
1417/* returns bit state 1421/* returns bit state