diff options
author | Lars Ellenberg <lars.ellenberg@linbit.com> | 2011-02-23 11:02:01 -0500 |
---|---|---|
committer | Philipp Reisner <philipp.reisner@linbit.com> | 2012-05-09 09:17:07 -0400 |
commit | 9476f39d66041ca8c66546671765b4047bffa895 (patch) | |
tree | 1416c0522fab3c228834cafbe1e1463e7900a0d0 | |
parent | 3c2f7a856f2e70d2f1bb59f65d97a66047f14f36 (diff) |
drbd: introduce a bio_set to allocate housekeeping bios from
Don't rely on availability of bios from the global fs_bio_set,
we should use our own bio_set for meta data IO.
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
-rw-r--r-- | drivers/block/drbd/drbd_actlog.c | 2 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_bitmap.c | 3 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_int.h | 6 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_main.c | 30 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_receiver.c | 6 |
5 files changed, 43 insertions, 4 deletions
diff --git a/drivers/block/drbd/drbd_actlog.c b/drivers/block/drbd/drbd_actlog.c index 0a35f82f1222..e54e31b02b88 100644 --- a/drivers/block/drbd/drbd_actlog.c +++ b/drivers/block/drbd/drbd_actlog.c | |||
@@ -115,7 +115,7 @@ static int _drbd_md_sync_page_io(struct drbd_conf *mdev, | |||
115 | rw |= REQ_FUA | REQ_FLUSH; | 115 | rw |= REQ_FUA | REQ_FLUSH; |
116 | rw |= REQ_SYNC; | 116 | rw |= REQ_SYNC; |
117 | 117 | ||
118 | bio = bio_alloc(GFP_NOIO, 1); | 118 | bio = bio_alloc_drbd(GFP_NOIO); |
119 | bio->bi_bdev = bdev->md_bdev; | 119 | bio->bi_bdev = bdev->md_bdev; |
120 | bio->bi_sector = sector; | 120 | bio->bi_sector = sector; |
121 | ok = (bio_add_page(bio, page, size, 0) == size); | 121 | ok = (bio_add_page(bio, page, size, 0) == size); |
diff --git a/drivers/block/drbd/drbd_bitmap.c b/drivers/block/drbd/drbd_bitmap.c index a24eb787a7a1..b5c5ff53cb57 100644 --- a/drivers/block/drbd/drbd_bitmap.c +++ b/drivers/block/drbd/drbd_bitmap.c | |||
@@ -953,8 +953,7 @@ static void bm_async_io_complete(struct bio *bio, int error) | |||
953 | 953 | ||
954 | static void bm_page_io_async(struct bm_aio_ctx *ctx, int page_nr, int rw) __must_hold(local) | 954 | static void bm_page_io_async(struct bm_aio_ctx *ctx, int page_nr, int rw) __must_hold(local) |
955 | { | 955 | { |
956 | /* we are process context. we always get a bio */ | 956 | struct bio *bio = bio_alloc_drbd(GFP_NOIO); |
957 | struct bio *bio = bio_alloc(GFP_NOIO, 1); | ||
958 | struct drbd_conf *mdev = ctx->mdev; | 957 | struct drbd_conf *mdev = ctx->mdev; |
959 | struct drbd_bitmap *b = mdev->bitmap; | 958 | struct drbd_bitmap *b = mdev->bitmap; |
960 | struct page *page; | 959 | struct page *page; |
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index 685ed4cca173..02f013a073a7 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h | |||
@@ -1522,6 +1522,12 @@ extern wait_queue_head_t drbd_pp_wait; | |||
1522 | #define DRBD_MIN_POOL_PAGES 128 | 1522 | #define DRBD_MIN_POOL_PAGES 128 |
1523 | extern mempool_t *drbd_md_io_page_pool; | 1523 | extern mempool_t *drbd_md_io_page_pool; |
1524 | 1524 | ||
1525 | /* We also need to make sure we get a bio | ||
1526 | * when we need it for housekeeping purposes */ | ||
1527 | extern struct bio_set *drbd_md_io_bio_set; | ||
1528 | /* to allocate from that set */ | ||
1529 | extern struct bio *bio_alloc_drbd(gfp_t gfp_mask); | ||
1530 | |||
1525 | extern rwlock_t global_state_lock; | 1531 | extern rwlock_t global_state_lock; |
1526 | 1532 | ||
1527 | extern struct drbd_conf *drbd_new_device(unsigned int minor); | 1533 | extern struct drbd_conf *drbd_new_device(unsigned int minor); |
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index c03e87f19e86..bd380b94fd08 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c | |||
@@ -140,6 +140,7 @@ struct kmem_cache *drbd_al_ext_cache; /* activity log extents */ | |||
140 | mempool_t *drbd_request_mempool; | 140 | mempool_t *drbd_request_mempool; |
141 | mempool_t *drbd_ee_mempool; | 141 | mempool_t *drbd_ee_mempool; |
142 | mempool_t *drbd_md_io_page_pool; | 142 | mempool_t *drbd_md_io_page_pool; |
143 | struct bio_set *drbd_md_io_bio_set; | ||
143 | 144 | ||
144 | /* I do not use a standard mempool, because: | 145 | /* I do not use a standard mempool, because: |
145 | 1) I want to hand out the pre-allocated objects first. | 146 | 1) I want to hand out the pre-allocated objects first. |
@@ -160,6 +161,25 @@ static const struct block_device_operations drbd_ops = { | |||
160 | .release = drbd_release, | 161 | .release = drbd_release, |
161 | }; | 162 | }; |
162 | 163 | ||
164 | static void bio_destructor_drbd(struct bio *bio) | ||
165 | { | ||
166 | bio_free(bio, drbd_md_io_bio_set); | ||
167 | } | ||
168 | |||
169 | struct bio *bio_alloc_drbd(gfp_t gfp_mask) | ||
170 | { | ||
171 | struct bio *bio; | ||
172 | |||
173 | if (!drbd_md_io_bio_set) | ||
174 | return bio_alloc(gfp_mask, 1); | ||
175 | |||
176 | bio = bio_alloc_bioset(gfp_mask, 1, drbd_md_io_bio_set); | ||
177 | if (!bio) | ||
178 | return NULL; | ||
179 | bio->bi_destructor = bio_destructor_drbd; | ||
180 | return bio; | ||
181 | } | ||
182 | |||
163 | #ifdef __CHECKER__ | 183 | #ifdef __CHECKER__ |
164 | /* When checking with sparse, and this is an inline function, sparse will | 184 | /* When checking with sparse, and this is an inline function, sparse will |
165 | give tons of false positives. When this is a real functions sparse works. | 185 | give tons of false positives. When this is a real functions sparse works. |
@@ -3263,6 +3283,8 @@ static void drbd_destroy_mempools(void) | |||
3263 | 3283 | ||
3264 | /* D_ASSERT(atomic_read(&drbd_pp_vacant)==0); */ | 3284 | /* D_ASSERT(atomic_read(&drbd_pp_vacant)==0); */ |
3265 | 3285 | ||
3286 | if (drbd_md_io_bio_set) | ||
3287 | bioset_free(drbd_md_io_bio_set); | ||
3266 | if (drbd_md_io_page_pool) | 3288 | if (drbd_md_io_page_pool) |
3267 | mempool_destroy(drbd_md_io_page_pool); | 3289 | mempool_destroy(drbd_md_io_page_pool); |
3268 | if (drbd_ee_mempool) | 3290 | if (drbd_ee_mempool) |
@@ -3278,6 +3300,7 @@ static void drbd_destroy_mempools(void) | |||
3278 | if (drbd_al_ext_cache) | 3300 | if (drbd_al_ext_cache) |
3279 | kmem_cache_destroy(drbd_al_ext_cache); | 3301 | kmem_cache_destroy(drbd_al_ext_cache); |
3280 | 3302 | ||
3303 | drbd_md_io_bio_set = NULL; | ||
3281 | drbd_md_io_page_pool = NULL; | 3304 | drbd_md_io_page_pool = NULL; |
3282 | drbd_ee_mempool = NULL; | 3305 | drbd_ee_mempool = NULL; |
3283 | drbd_request_mempool = NULL; | 3306 | drbd_request_mempool = NULL; |
@@ -3303,6 +3326,7 @@ static int drbd_create_mempools(void) | |||
3303 | drbd_al_ext_cache = NULL; | 3326 | drbd_al_ext_cache = NULL; |
3304 | drbd_pp_pool = NULL; | 3327 | drbd_pp_pool = NULL; |
3305 | drbd_md_io_page_pool = NULL; | 3328 | drbd_md_io_page_pool = NULL; |
3329 | drbd_md_io_bio_set = NULL; | ||
3306 | 3330 | ||
3307 | /* caches */ | 3331 | /* caches */ |
3308 | drbd_request_cache = kmem_cache_create( | 3332 | drbd_request_cache = kmem_cache_create( |
@@ -3326,6 +3350,12 @@ static int drbd_create_mempools(void) | |||
3326 | goto Enomem; | 3350 | goto Enomem; |
3327 | 3351 | ||
3328 | /* mempools */ | 3352 | /* mempools */ |
3353 | #ifdef COMPAT_HAVE_BIOSET_CREATE | ||
3354 | drbd_md_io_bio_set = bioset_create(DRBD_MIN_POOL_PAGES, 0); | ||
3355 | if (drbd_md_io_bio_set == NULL) | ||
3356 | goto Enomem; | ||
3357 | #endif | ||
3358 | |||
3329 | drbd_md_io_page_pool = mempool_create_page_pool(DRBD_MIN_POOL_PAGES, 0); | 3359 | drbd_md_io_page_pool = mempool_create_page_pool(DRBD_MIN_POOL_PAGES, 0); |
3330 | if (drbd_md_io_page_pool == NULL) | 3360 | if (drbd_md_io_page_pool == NULL) |
3331 | goto Enomem; | 3361 | goto Enomem; |
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index 017eeb745ed9..247a79aec895 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c | |||
@@ -1106,7 +1106,11 @@ int drbd_submit_ee(struct drbd_conf *mdev, struct drbd_epoch_entry *e, | |||
1106 | /* In most cases, we will only need one bio. But in case the lower | 1106 | /* In most cases, we will only need one bio. But in case the lower |
1107 | * level restrictions happen to be different at this offset on this | 1107 | * level restrictions happen to be different at this offset on this |
1108 | * side than those of the sending peer, we may need to submit the | 1108 | * side than those of the sending peer, we may need to submit the |
1109 | * request in more than one bio. */ | 1109 | * request in more than one bio. |
1110 | * | ||
1111 | * Plain bio_alloc is good enough here, this is no DRBD internally | ||
1112 | * generated bio, but a bio allocated on behalf of the peer. | ||
1113 | */ | ||
1110 | next_bio: | 1114 | next_bio: |
1111 | bio = bio_alloc(GFP_NOIO, nr_pages); | 1115 | bio = bio_alloc(GFP_NOIO, nr_pages); |
1112 | if (!bio) { | 1116 | if (!bio) { |