Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit da67e68f authored by Javier González's avatar Javier González Committed by Jens Axboe
Browse files

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: a4bd217b ("lightnvm: physical block device (pblk) target")
Signed-off-by: default avatarJavier González <javier@cnexlabs.com>
Signed-off-by: default avatarMatias Bjørling <m@bjorling.me>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent e0e12a70
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -46,7 +46,7 @@ static int pblk_rw_io(struct request_queue *q, struct pblk *pblk,
	 * user I/Os. Unless stalled, the rate limiter leaves at least 256KB
	 * user I/Os. Unless stalled, the rate limiter leaves at least 256KB
	 * available for user I/O.
	 * available for user I/O.
	 */
	 */
	if (unlikely(pblk_get_secs(bio) >= pblk_rl_sysfs_rate_show(&pblk->rl)))
	if (pblk_get_secs(bio) > pblk_rl_max_io(&pblk->rl))
		blk_queue_split(q, &bio);
		blk_queue_split(q, &bio);


	return pblk_write_to_cache(pblk, bio, PBLK_IOTYPE_USER);
	return pblk_write_to_cache(pblk, bio, PBLK_IOTYPE_USER);
+6 −0
Original line number Original line Diff line number Diff line
@@ -163,6 +163,11 @@ int pblk_rl_sysfs_rate_show(struct pblk_rl *rl)
	return rl->rb_user_max;
	return rl->rb_user_max;
}
}


int pblk_rl_max_io(struct pblk_rl *rl)
{
	return rl->rb_max_io;
}

static void pblk_rl_u_timer(unsigned long data)
static void pblk_rl_u_timer(unsigned long data)
{
{
	struct pblk_rl *rl = (struct pblk_rl *)data;
	struct pblk_rl *rl = (struct pblk_rl *)data;
@@ -199,6 +204,7 @@ void pblk_rl_init(struct pblk_rl *rl, int budget)
	/* To start with, all buffer is available to user I/O writers */
	/* To start with, all buffer is available to user I/O writers */
	rl->rb_budget = budget;
	rl->rb_budget = budget;
	rl->rb_user_max = budget;
	rl->rb_user_max = budget;
	rl->rb_max_io = budget >> 1;
	rl->rb_gc_max = 0;
	rl->rb_gc_max = 0;
	rl->rb_state = PBLK_RL_HIGH;
	rl->rb_state = PBLK_RL_HIGH;


+2 −0
Original line number Original line Diff line number Diff line
@@ -267,6 +267,7 @@ struct pblk_rl {
	int rb_gc_max;		/* Max buffer entries available for GC I/O */
	int rb_gc_max;		/* Max buffer entries available for GC I/O */
	int rb_gc_rsv;		/* Reserved buffer entries for GC I/O */
	int rb_gc_rsv;		/* Reserved buffer entries for GC I/O */
	int rb_state;		/* Rate-limiter current state */
	int rb_state;		/* Rate-limiter current state */
	int rb_max_io;		/* Maximum size for an I/O giving the config */


	atomic_t rb_user_cnt;	/* User I/O buffer counter */
	atomic_t rb_user_cnt;	/* User I/O buffer counter */
	atomic_t rb_gc_cnt;	/* GC I/O buffer counter */
	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);
void pblk_rl_gc_in(struct pblk_rl *rl, int nr_entries);
void pblk_rl_gc_in(struct pblk_rl *rl, int nr_entries);
void pblk_rl_out(struct pblk_rl *rl, int nr_user, int nr_gc);
void pblk_rl_out(struct pblk_rl *rl, int nr_user, int nr_gc);
int pblk_rl_sysfs_rate_show(struct pblk_rl *rl);
int pblk_rl_sysfs_rate_show(struct pblk_rl *rl);
int pblk_rl_max_io(struct pblk_rl *rl);
void pblk_rl_free_lines_inc(struct pblk_rl *rl, struct pblk_line *line);
void pblk_rl_free_lines_inc(struct pblk_rl *rl, struct pblk_line *line);
void pblk_rl_free_lines_dec(struct pblk_rl *rl, struct pblk_line *line);
void pblk_rl_free_lines_dec(struct pblk_rl *rl, struct pblk_line *line);
void pblk_rl_set_space_limit(struct pblk_rl *rl, int entries_left);
void pblk_rl_set_space_limit(struct pblk_rl *rl, int entries_left);