| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0 |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Copyright (C) 2016 CNEX Labs |
|---|
| 3 | 4 | * Initial release: Javier Gonzalez <javier@cnexlabs.com> |
|---|
| .. | .. |
|---|
| 127 | 128 | } else if (free_blocks < rl->high) { |
|---|
| 128 | 129 | int shift = rl->high_pw - rl->rb_windows_pw; |
|---|
| 129 | 130 | int user_windows = free_blocks >> shift; |
|---|
| 130 | | - int user_max = user_windows << PBLK_MAX_REQ_ADDRS_PW; |
|---|
| 131 | + int user_max = user_windows << ilog2(NVM_MAX_VLBA); |
|---|
| 131 | 132 | |
|---|
| 132 | 133 | rl->rb_user_max = user_max; |
|---|
| 133 | 134 | rl->rb_gc_max = max - user_max; |
|---|
| .. | .. |
|---|
| 206 | 207 | del_timer(&rl->u_timer); |
|---|
| 207 | 208 | } |
|---|
| 208 | 209 | |
|---|
| 209 | | -void pblk_rl_init(struct pblk_rl *rl, int budget) |
|---|
| 210 | +void pblk_rl_init(struct pblk_rl *rl, int budget, int threshold) |
|---|
| 210 | 211 | { |
|---|
| 211 | 212 | struct pblk *pblk = container_of(rl, struct pblk, rl); |
|---|
| 212 | 213 | struct nvm_tgt_dev *dev = pblk->dev; |
|---|
| 213 | 214 | struct nvm_geo *geo = &dev->geo; |
|---|
| 214 | 215 | struct pblk_line_mgmt *l_mg = &pblk->l_mg; |
|---|
| 215 | 216 | struct pblk_line_meta *lm = &pblk->lm; |
|---|
| 216 | | - int min_blocks = lm->blk_per_line * PBLK_GC_RSV_LINE; |
|---|
| 217 | 217 | int sec_meta, blk_meta; |
|---|
| 218 | | - |
|---|
| 219 | 218 | unsigned int rb_windows; |
|---|
| 220 | 219 | |
|---|
| 221 | 220 | /* Consider sectors used for metadata */ |
|---|
| .. | .. |
|---|
| 225 | 224 | rl->high = pblk->op_blks - blk_meta - lm->blk_per_line; |
|---|
| 226 | 225 | rl->high_pw = get_count_order(rl->high); |
|---|
| 227 | 226 | |
|---|
| 228 | | - rl->rsv_blocks = min_blocks; |
|---|
| 227 | + rl->rsv_blocks = pblk_get_min_chks(pblk); |
|---|
| 229 | 228 | |
|---|
| 230 | 229 | /* This will always be a power-of-2 */ |
|---|
| 231 | | - rb_windows = budget / PBLK_MAX_REQ_ADDRS; |
|---|
| 230 | + rb_windows = budget / NVM_MAX_VLBA; |
|---|
| 232 | 231 | rl->rb_windows_pw = get_count_order(rb_windows); |
|---|
| 233 | 232 | |
|---|
| 234 | 233 | /* To start with, all buffer is available to user I/O writers */ |
|---|
| 235 | 234 | rl->rb_budget = budget; |
|---|
| 236 | 235 | rl->rb_user_max = budget; |
|---|
| 237 | | - rl->rb_max_io = budget >> 1; |
|---|
| 238 | 236 | rl->rb_gc_max = 0; |
|---|
| 239 | 237 | rl->rb_state = PBLK_RL_HIGH; |
|---|
| 240 | 238 | |
|---|
| 239 | + /* Maximize I/O size and ansure that back threshold is respected */ |
|---|
| 240 | + if (threshold) |
|---|
| 241 | + rl->rb_max_io = budget - pblk->min_write_pgs_data - threshold; |
|---|
| 242 | + else |
|---|
| 243 | + rl->rb_max_io = budget - pblk->min_write_pgs_data - 1; |
|---|
| 244 | + |
|---|
| 241 | 245 | atomic_set(&rl->rb_user_cnt, 0); |
|---|
| 242 | 246 | atomic_set(&rl->rb_gc_cnt, 0); |
|---|
| 243 | 247 | atomic_set(&rl->rb_space, -1); |
|---|