diff options
author | Javier González <javier@cnexlabs.com> | 2017-10-13 08:46:05 -0400 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2017-10-13 10:34:57 -0400 |
commit | da67e68fb9d37fb9072b20cc75d4337a73bc01b4 (patch) | |
tree | 81f0a1b1872dfaf14959b8f8b730bafcf512c309 /drivers/lightnvm | |
parent | e0e12a707f02fcde1b77a2417d9fb0ae1ce3b003 (diff) |
lightnvm: pblk: avoid deadlock on low LUN config
On low LUN configurations, make sure not to send bios that are bigger
than the buffer size.
Fixes: a4bd217b4326 ("lightnvm: physical block device (pblk) target")
Signed-off-by: Javier González <javier@cnexlabs.com>
Signed-off-by: Matias Bjørling <m@bjorling.me>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'drivers/lightnvm')
-rw-r--r-- | drivers/lightnvm/pblk-init.c | 2 | ||||
-rw-r--r-- | drivers/lightnvm/pblk-rl.c | 6 | ||||
-rw-r--r-- | drivers/lightnvm/pblk.h | 2 |
3 files changed, 9 insertions, 1 deletions
diff --git a/drivers/lightnvm/pblk-init.c b/drivers/lightnvm/pblk-init.c index 83445115a922..eee4eeb47d07 100644 --- a/drivers/lightnvm/pblk-init.c +++ b/drivers/lightnvm/pblk-init.c | |||
@@ -46,7 +46,7 @@ static int pblk_rw_io(struct request_queue *q, struct pblk *pblk, | |||
46 | * user I/Os. Unless stalled, the rate limiter leaves at least 256KB | 46 | * user I/Os. Unless stalled, the rate limiter leaves at least 256KB |
47 | * available for user I/O. | 47 | * available for user I/O. |
48 | */ | 48 | */ |
49 | if (unlikely(pblk_get_secs(bio) >= pblk_rl_sysfs_rate_show(&pblk->rl))) | 49 | if (pblk_get_secs(bio) > pblk_rl_max_io(&pblk->rl)) |
50 | blk_queue_split(q, &bio); | 50 | blk_queue_split(q, &bio); |
51 | 51 | ||
52 | return pblk_write_to_cache(pblk, bio, PBLK_IOTYPE_USER); | 52 | return pblk_write_to_cache(pblk, bio, PBLK_IOTYPE_USER); |
diff --git a/drivers/lightnvm/pblk-rl.c b/drivers/lightnvm/pblk-rl.c index 9565c3bc4d0b..0896439a91b0 100644 --- a/drivers/lightnvm/pblk-rl.c +++ b/drivers/lightnvm/pblk-rl.c | |||
@@ -163,6 +163,11 @@ int pblk_rl_sysfs_rate_show(struct pblk_rl *rl) | |||
163 | return rl->rb_user_max; | 163 | return rl->rb_user_max; |
164 | } | 164 | } |
165 | 165 | ||
166 | int pblk_rl_max_io(struct pblk_rl *rl) | ||
167 | { | ||
168 | return rl->rb_max_io; | ||
169 | } | ||
170 | |||
166 | static void pblk_rl_u_timer(unsigned long data) | 171 | static void pblk_rl_u_timer(unsigned long data) |
167 | { | 172 | { |
168 | struct pblk_rl *rl = (struct pblk_rl *)data; | 173 | struct pblk_rl *rl = (struct pblk_rl *)data; |
@@ -199,6 +204,7 @@ void pblk_rl_init(struct pblk_rl *rl, int budget) | |||
199 | /* To start with, all buffer is available to user I/O writers */ | 204 | /* To start with, all buffer is available to user I/O writers */ |
200 | rl->rb_budget = budget; | 205 | rl->rb_budget = budget; |
201 | rl->rb_user_max = budget; | 206 | rl->rb_user_max = budget; |
207 | rl->rb_max_io = budget >> 1; | ||
202 | rl->rb_gc_max = 0; | 208 | rl->rb_gc_max = 0; |
203 | rl->rb_state = PBLK_RL_HIGH; | 209 | rl->rb_state = PBLK_RL_HIGH; |
204 | 210 | ||
diff --git a/drivers/lightnvm/pblk.h b/drivers/lightnvm/pblk.h index 3a07c5b61a0c..b592e5194b0f 100644 --- a/drivers/lightnvm/pblk.h +++ b/drivers/lightnvm/pblk.h | |||
@@ -267,6 +267,7 @@ struct pblk_rl { | |||
267 | int rb_gc_max; /* Max buffer entries available for GC I/O */ | 267 | int rb_gc_max; /* Max buffer entries available for GC I/O */ |
268 | int rb_gc_rsv; /* Reserved buffer entries for GC I/O */ | 268 | int rb_gc_rsv; /* Reserved buffer entries for GC I/O */ |
269 | int rb_state; /* Rate-limiter current state */ | 269 | int rb_state; /* Rate-limiter current state */ |
270 | int rb_max_io; /* Maximum size for an I/O giving the config */ | ||
270 | 271 | ||
271 | atomic_t rb_user_cnt; /* User I/O buffer counter */ | 272 | atomic_t rb_user_cnt; /* User I/O buffer counter */ |
272 | atomic_t rb_gc_cnt; /* GC I/O buffer counter */ | 273 | atomic_t rb_gc_cnt; /* GC I/O buffer counter */ |
@@ -844,6 +845,7 @@ int pblk_rl_gc_may_insert(struct pblk_rl *rl, int nr_entries); | |||
844 | void pblk_rl_gc_in(struct pblk_rl *rl, int nr_entries); | 845 | void pblk_rl_gc_in(struct pblk_rl *rl, int nr_entries); |
845 | void pblk_rl_out(struct pblk_rl *rl, int nr_user, int nr_gc); | 846 | void pblk_rl_out(struct pblk_rl *rl, int nr_user, int nr_gc); |
846 | int pblk_rl_sysfs_rate_show(struct pblk_rl *rl); | 847 | int pblk_rl_sysfs_rate_show(struct pblk_rl *rl); |
848 | int pblk_rl_max_io(struct pblk_rl *rl); | ||
847 | void pblk_rl_free_lines_inc(struct pblk_rl *rl, struct pblk_line *line); | 849 | void pblk_rl_free_lines_inc(struct pblk_rl *rl, struct pblk_line *line); |
848 | void pblk_rl_free_lines_dec(struct pblk_rl *rl, struct pblk_line *line); | 850 | void pblk_rl_free_lines_dec(struct pblk_rl *rl, struct pblk_line *line); |
849 | void pblk_rl_set_space_limit(struct pblk_rl *rl, int entries_left); | 851 | void pblk_rl_set_space_limit(struct pblk_rl *rl, int entries_left); |