pblk-recovery.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (C) 2016 CNEX Labs
  4. * Initial: Javier Gonzalez <javier@cnexlabs.com>
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License version
  8. * 2 as published by the Free Software Foundation.
  9. *
  10. * This program is distributed in the hope that it will be useful, but
  11. * WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * General Public License for more details.
  14. *
  15. * pblk-recovery.c - pblk's recovery path
  16. *
  17. * The L2P recovery path is single threaded as the L2P table is updated in order
  18. * following the line sequence ID.
  19. */
  20. #include "pblk.h"
  21. #include "pblk-trace.h"
  22. int pblk_recov_check_emeta(struct pblk *pblk, struct line_emeta *emeta_buf)
  23. {
  24. u32 crc;
  25. crc = pblk_calc_emeta_crc(pblk, emeta_buf);
  26. if (le32_to_cpu(emeta_buf->crc) != crc)
  27. return 1;
  28. if (le32_to_cpu(emeta_buf->header.identifier) != PBLK_MAGIC)
  29. return 1;
  30. return 0;
  31. }
  32. static int pblk_recov_l2p_from_emeta(struct pblk *pblk, struct pblk_line *line)
  33. {
  34. struct nvm_tgt_dev *dev = pblk->dev;
  35. struct nvm_geo *geo = &dev->geo;
  36. struct pblk_line_meta *lm = &pblk->lm;
  37. struct pblk_emeta *emeta = line->emeta;
  38. struct line_emeta *emeta_buf = emeta->buf;
  39. __le64 *lba_list;
  40. u64 data_start, data_end;
  41. u64 nr_valid_lbas, nr_lbas = 0;
  42. u64 i;
  43. lba_list = emeta_to_lbas(pblk, emeta_buf);
  44. if (!lba_list)
  45. return 1;
  46. data_start = pblk_line_smeta_start(pblk, line) + lm->smeta_sec;
  47. data_end = line->emeta_ssec;
  48. nr_valid_lbas = le64_to_cpu(emeta_buf->nr_valid_lbas);
  49. for (i = data_start; i < data_end; i++) {
  50. struct ppa_addr ppa;
  51. int pos;
  52. ppa = addr_to_gen_ppa(pblk, i, line->id);
  53. pos = pblk_ppa_to_pos(geo, ppa);
  54. /* Do not update bad blocks */
  55. if (test_bit(pos, line->blk_bitmap))
  56. continue;
  57. if (le64_to_cpu(lba_list[i]) == ADDR_EMPTY) {
  58. spin_lock(&line->lock);
  59. if (test_and_set_bit(i, line->invalid_bitmap))
  60. WARN_ONCE(1, "pblk: rec. double invalidate:\n");
  61. else
  62. le32_add_cpu(line->vsc, -1);
  63. spin_unlock(&line->lock);
  64. continue;
  65. }
  66. pblk_update_map(pblk, le64_to_cpu(lba_list[i]), ppa);
  67. nr_lbas++;
  68. }
  69. if (nr_valid_lbas != nr_lbas)
  70. pblk_err(pblk, "line %d - inconsistent lba list(%llu/%llu)\n",
  71. line->id, nr_valid_lbas, nr_lbas);
  72. line->left_msecs = 0;
  73. return 0;
  74. }
  75. static void pblk_update_line_wp(struct pblk *pblk, struct pblk_line *line,
  76. u64 written_secs)
  77. {
  78. struct pblk_line_mgmt *l_mg = &pblk->l_mg;
  79. int i;
  80. for (i = 0; i < written_secs; i += pblk->min_write_pgs)
  81. __pblk_alloc_page(pblk, line, pblk->min_write_pgs);
  82. spin_lock(&l_mg->free_lock);
  83. if (written_secs > line->left_msecs) {
  84. /*
  85. * We have all data sectors written
  86. * and some emeta sectors written too.
  87. */
  88. line->left_msecs = 0;
  89. } else {
  90. /* We have only some data sectors written. */
  91. line->left_msecs -= written_secs;
  92. }
  93. spin_unlock(&l_mg->free_lock);
  94. }
  95. static u64 pblk_sec_in_open_line(struct pblk *pblk, struct pblk_line *line)
  96. {
  97. struct pblk_line_meta *lm = &pblk->lm;
  98. int nr_bb = bitmap_weight(line->blk_bitmap, lm->blk_per_line);
  99. u64 written_secs = 0;
  100. int valid_chunks = 0;
  101. int i;
  102. for (i = 0; i < lm->blk_per_line; i++) {
  103. struct nvm_chk_meta *chunk = &line->chks[i];
  104. if (chunk->state & NVM_CHK_ST_OFFLINE)
  105. continue;
  106. written_secs += chunk->wp;
  107. valid_chunks++;
  108. }
  109. if (lm->blk_per_line - nr_bb != valid_chunks)
  110. pblk_err(pblk, "recovery line %d is bad\n", line->id);
  111. pblk_update_line_wp(pblk, line, written_secs - lm->smeta_sec);
  112. return written_secs;
  113. }
  114. struct pblk_recov_alloc {
  115. struct ppa_addr *ppa_list;
  116. void *meta_list;
  117. struct nvm_rq *rqd;
  118. void *data;
  119. dma_addr_t dma_ppa_list;
  120. dma_addr_t dma_meta_list;
  121. };
  122. static void pblk_recov_complete(struct kref *ref)
  123. {
  124. struct pblk_pad_rq *pad_rq = container_of(ref, struct pblk_pad_rq, ref);
  125. complete(&pad_rq->wait);
  126. }
  127. static void pblk_end_io_recov(struct nvm_rq *rqd)
  128. {
  129. struct ppa_addr *ppa_list = nvm_rq_to_ppa_list(rqd);
  130. struct pblk_pad_rq *pad_rq = rqd->private;
  131. struct pblk *pblk = pad_rq->pblk;
  132. pblk_up_chunk(pblk, ppa_list[0]);
  133. pblk_free_rqd(pblk, rqd, PBLK_WRITE_INT);
  134. atomic_dec(&pblk->inflight_io);
  135. kref_put(&pad_rq->ref, pblk_recov_complete);
  136. }
  137. /* pad line using line bitmap. */
  138. static int pblk_recov_pad_line(struct pblk *pblk, struct pblk_line *line,
  139. int left_ppas)
  140. {
  141. struct nvm_tgt_dev *dev = pblk->dev;
  142. struct nvm_geo *geo = &dev->geo;
  143. void *meta_list;
  144. struct pblk_pad_rq *pad_rq;
  145. struct nvm_rq *rqd;
  146. struct ppa_addr *ppa_list;
  147. void *data;
  148. __le64 *lba_list = emeta_to_lbas(pblk, line->emeta->buf);
  149. u64 w_ptr = line->cur_sec;
  150. int left_line_ppas, rq_ppas;
  151. int i, j;
  152. int ret = 0;
  153. spin_lock(&line->lock);
  154. left_line_ppas = line->left_msecs;
  155. spin_unlock(&line->lock);
  156. pad_rq = kmalloc(sizeof(struct pblk_pad_rq), GFP_KERNEL);
  157. if (!pad_rq)
  158. return -ENOMEM;
  159. data = vzalloc(array_size(pblk->max_write_pgs, geo->csecs));
  160. if (!data) {
  161. ret = -ENOMEM;
  162. goto free_rq;
  163. }
  164. pad_rq->pblk = pblk;
  165. init_completion(&pad_rq->wait);
  166. kref_init(&pad_rq->ref);
  167. next_pad_rq:
  168. rq_ppas = pblk_calc_secs(pblk, left_ppas, 0, false);
  169. if (rq_ppas < pblk->min_write_pgs) {
  170. pblk_err(pblk, "corrupted pad line %d\n", line->id);
  171. goto fail_complete;
  172. }
  173. rqd = pblk_alloc_rqd(pblk, PBLK_WRITE_INT);
  174. ret = pblk_alloc_rqd_meta(pblk, rqd);
  175. if (ret) {
  176. pblk_free_rqd(pblk, rqd, PBLK_WRITE_INT);
  177. goto fail_complete;
  178. }
  179. rqd->bio = NULL;
  180. rqd->opcode = NVM_OP_PWRITE;
  181. rqd->is_seq = 1;
  182. rqd->nr_ppas = rq_ppas;
  183. rqd->end_io = pblk_end_io_recov;
  184. rqd->private = pad_rq;
  185. ppa_list = nvm_rq_to_ppa_list(rqd);
  186. meta_list = rqd->meta_list;
  187. for (i = 0; i < rqd->nr_ppas; ) {
  188. struct ppa_addr ppa;
  189. int pos;
  190. w_ptr = pblk_alloc_page(pblk, line, pblk->min_write_pgs);
  191. ppa = addr_to_gen_ppa(pblk, w_ptr, line->id);
  192. pos = pblk_ppa_to_pos(geo, ppa);
  193. while (test_bit(pos, line->blk_bitmap)) {
  194. w_ptr += pblk->min_write_pgs;
  195. ppa = addr_to_gen_ppa(pblk, w_ptr, line->id);
  196. pos = pblk_ppa_to_pos(geo, ppa);
  197. }
  198. for (j = 0; j < pblk->min_write_pgs; j++, i++, w_ptr++) {
  199. struct ppa_addr dev_ppa;
  200. struct pblk_sec_meta *meta;
  201. __le64 addr_empty = cpu_to_le64(ADDR_EMPTY);
  202. dev_ppa = addr_to_gen_ppa(pblk, w_ptr, line->id);
  203. pblk_map_invalidate(pblk, dev_ppa);
  204. lba_list[w_ptr] = addr_empty;
  205. meta = pblk_get_meta(pblk, meta_list, i);
  206. meta->lba = addr_empty;
  207. ppa_list[i] = dev_ppa;
  208. }
  209. }
  210. kref_get(&pad_rq->ref);
  211. pblk_down_chunk(pblk, ppa_list[0]);
  212. ret = pblk_submit_io(pblk, rqd, data);
  213. if (ret) {
  214. pblk_err(pblk, "I/O submission failed: %d\n", ret);
  215. pblk_up_chunk(pblk, ppa_list[0]);
  216. kref_put(&pad_rq->ref, pblk_recov_complete);
  217. pblk_free_rqd(pblk, rqd, PBLK_WRITE_INT);
  218. goto fail_complete;
  219. }
  220. left_line_ppas -= rq_ppas;
  221. left_ppas -= rq_ppas;
  222. if (left_ppas && left_line_ppas)
  223. goto next_pad_rq;
  224. fail_complete:
  225. kref_put(&pad_rq->ref, pblk_recov_complete);
  226. wait_for_completion(&pad_rq->wait);
  227. if (!pblk_line_is_full(line))
  228. pblk_err(pblk, "corrupted padded line: %d\n", line->id);
  229. vfree(data);
  230. free_rq:
  231. kfree(pad_rq);
  232. return ret;
  233. }
  234. static int pblk_pad_distance(struct pblk *pblk, struct pblk_line *line)
  235. {
  236. struct nvm_tgt_dev *dev = pblk->dev;
  237. struct nvm_geo *geo = &dev->geo;
  238. int distance = geo->mw_cunits * geo->all_luns * geo->ws_opt;
  239. return (distance > line->left_msecs) ? line->left_msecs : distance;
  240. }
  241. /* Return a chunk belonging to a line by stripe(write order) index */
  242. static struct nvm_chk_meta *pblk_get_stripe_chunk(struct pblk *pblk,
  243. struct pblk_line *line,
  244. int index)
  245. {
  246. struct nvm_tgt_dev *dev = pblk->dev;
  247. struct nvm_geo *geo = &dev->geo;
  248. struct pblk_lun *rlun;
  249. struct ppa_addr ppa;
  250. int pos;
  251. rlun = &pblk->luns[index];
  252. ppa = rlun->bppa;
  253. pos = pblk_ppa_to_pos(geo, ppa);
  254. return &line->chks[pos];
  255. }
  256. static int pblk_line_wps_are_unbalanced(struct pblk *pblk,
  257. struct pblk_line *line)
  258. {
  259. struct pblk_line_meta *lm = &pblk->lm;
  260. int blk_in_line = lm->blk_per_line;
  261. struct nvm_chk_meta *chunk;
  262. u64 max_wp, min_wp;
  263. int i;
  264. i = find_first_zero_bit(line->blk_bitmap, blk_in_line);
  265. /* If there is one or zero good chunks in the line,
  266. * the write pointers can't be unbalanced.
  267. */
  268. if (i >= (blk_in_line - 1))
  269. return 0;
  270. chunk = pblk_get_stripe_chunk(pblk, line, i);
  271. max_wp = chunk->wp;
  272. if (max_wp > pblk->max_write_pgs)
  273. min_wp = max_wp - pblk->max_write_pgs;
  274. else
  275. min_wp = 0;
  276. i = find_next_zero_bit(line->blk_bitmap, blk_in_line, i + 1);
  277. while (i < blk_in_line) {
  278. chunk = pblk_get_stripe_chunk(pblk, line, i);
  279. if (chunk->wp > max_wp || chunk->wp < min_wp)
  280. return 1;
  281. i = find_next_zero_bit(line->blk_bitmap, blk_in_line, i + 1);
  282. }
  283. return 0;
  284. }
  285. static int pblk_recov_scan_oob(struct pblk *pblk, struct pblk_line *line,
  286. struct pblk_recov_alloc p)
  287. {
  288. struct nvm_tgt_dev *dev = pblk->dev;
  289. struct pblk_line_meta *lm = &pblk->lm;
  290. struct nvm_geo *geo = &dev->geo;
  291. struct ppa_addr *ppa_list;
  292. void *meta_list;
  293. struct nvm_rq *rqd;
  294. void *data;
  295. dma_addr_t dma_ppa_list, dma_meta_list;
  296. __le64 *lba_list;
  297. u64 paddr = pblk_line_smeta_start(pblk, line) + lm->smeta_sec;
  298. bool padded = false;
  299. int rq_ppas;
  300. int i, j;
  301. int ret;
  302. u64 left_ppas = pblk_sec_in_open_line(pblk, line) - lm->smeta_sec;
  303. if (pblk_line_wps_are_unbalanced(pblk, line))
  304. pblk_warn(pblk, "recovering unbalanced line (%d)\n", line->id);
  305. ppa_list = p.ppa_list;
  306. meta_list = p.meta_list;
  307. rqd = p.rqd;
  308. data = p.data;
  309. dma_ppa_list = p.dma_ppa_list;
  310. dma_meta_list = p.dma_meta_list;
  311. lba_list = emeta_to_lbas(pblk, line->emeta->buf);
  312. next_rq:
  313. memset(rqd, 0, pblk_g_rq_size);
  314. rq_ppas = pblk_calc_secs(pblk, left_ppas, 0, false);
  315. if (!rq_ppas)
  316. rq_ppas = pblk->min_write_pgs;
  317. retry_rq:
  318. rqd->bio = NULL;
  319. rqd->opcode = NVM_OP_PREAD;
  320. rqd->meta_list = meta_list;
  321. rqd->nr_ppas = rq_ppas;
  322. rqd->ppa_list = ppa_list;
  323. rqd->dma_ppa_list = dma_ppa_list;
  324. rqd->dma_meta_list = dma_meta_list;
  325. ppa_list = nvm_rq_to_ppa_list(rqd);
  326. if (pblk_io_aligned(pblk, rq_ppas))
  327. rqd->is_seq = 1;
  328. for (i = 0; i < rqd->nr_ppas; ) {
  329. struct ppa_addr ppa;
  330. int pos;
  331. ppa = addr_to_gen_ppa(pblk, paddr, line->id);
  332. pos = pblk_ppa_to_pos(geo, ppa);
  333. while (test_bit(pos, line->blk_bitmap)) {
  334. paddr += pblk->min_write_pgs;
  335. ppa = addr_to_gen_ppa(pblk, paddr, line->id);
  336. pos = pblk_ppa_to_pos(geo, ppa);
  337. }
  338. for (j = 0; j < pblk->min_write_pgs; j++, i++)
  339. ppa_list[i] =
  340. addr_to_gen_ppa(pblk, paddr + j, line->id);
  341. }
  342. ret = pblk_submit_io_sync(pblk, rqd, data);
  343. if (ret) {
  344. pblk_err(pblk, "I/O submission failed: %d\n", ret);
  345. return ret;
  346. }
  347. atomic_dec(&pblk->inflight_io);
  348. /* If a read fails, do a best effort by padding the line and retrying */
  349. if (rqd->error && rqd->error != NVM_RSP_WARN_HIGHECC) {
  350. int pad_distance, ret;
  351. if (padded) {
  352. pblk_log_read_err(pblk, rqd);
  353. return -EINTR;
  354. }
  355. pad_distance = pblk_pad_distance(pblk, line);
  356. ret = pblk_recov_pad_line(pblk, line, pad_distance);
  357. if (ret) {
  358. return ret;
  359. }
  360. padded = true;
  361. goto retry_rq;
  362. }
  363. pblk_get_packed_meta(pblk, rqd);
  364. for (i = 0; i < rqd->nr_ppas; i++) {
  365. struct pblk_sec_meta *meta = pblk_get_meta(pblk, meta_list, i);
  366. u64 lba = le64_to_cpu(meta->lba);
  367. lba_list[paddr++] = cpu_to_le64(lba);
  368. if (lba == ADDR_EMPTY || lba >= pblk->capacity)
  369. continue;
  370. line->nr_valid_lbas++;
  371. pblk_update_map(pblk, lba, ppa_list[i]);
  372. }
  373. left_ppas -= rq_ppas;
  374. if (left_ppas > 0)
  375. goto next_rq;
  376. #ifdef CONFIG_NVM_PBLK_DEBUG
  377. WARN_ON(padded && !pblk_line_is_full(line));
  378. #endif
  379. return 0;
  380. }
  381. /* Scan line for lbas on out of bound area */
  382. static int pblk_recov_l2p_from_oob(struct pblk *pblk, struct pblk_line *line)
  383. {
  384. struct nvm_tgt_dev *dev = pblk->dev;
  385. struct nvm_geo *geo = &dev->geo;
  386. struct nvm_rq *rqd;
  387. struct ppa_addr *ppa_list;
  388. void *meta_list;
  389. struct pblk_recov_alloc p;
  390. void *data;
  391. dma_addr_t dma_ppa_list, dma_meta_list;
  392. int ret = 0;
  393. meta_list = nvm_dev_dma_alloc(dev->parent, GFP_KERNEL, &dma_meta_list);
  394. if (!meta_list)
  395. return -ENOMEM;
  396. ppa_list = (void *)(meta_list) + pblk_dma_meta_size(pblk);
  397. dma_ppa_list = dma_meta_list + pblk_dma_meta_size(pblk);
  398. data = kcalloc(pblk->max_write_pgs, geo->csecs, GFP_KERNEL);
  399. if (!data) {
  400. ret = -ENOMEM;
  401. goto free_meta_list;
  402. }
  403. rqd = mempool_alloc(&pblk->r_rq_pool, GFP_KERNEL);
  404. memset(rqd, 0, pblk_g_rq_size);
  405. p.ppa_list = ppa_list;
  406. p.meta_list = meta_list;
  407. p.rqd = rqd;
  408. p.data = data;
  409. p.dma_ppa_list = dma_ppa_list;
  410. p.dma_meta_list = dma_meta_list;
  411. ret = pblk_recov_scan_oob(pblk, line, p);
  412. if (ret) {
  413. pblk_err(pblk, "could not recover L2P form OOB\n");
  414. goto out;
  415. }
  416. if (pblk_line_is_full(line))
  417. pblk_line_recov_close(pblk, line);
  418. out:
  419. mempool_free(rqd, &pblk->r_rq_pool);
  420. kfree(data);
  421. free_meta_list:
  422. nvm_dev_dma_free(dev->parent, meta_list, dma_meta_list);
  423. return ret;
  424. }
  425. /* Insert lines ordered by sequence number (seq_num) on list */
  426. static void pblk_recov_line_add_ordered(struct list_head *head,
  427. struct pblk_line *line)
  428. {
  429. struct pblk_line *t = NULL;
  430. list_for_each_entry(t, head, list)
  431. if (t->seq_nr > line->seq_nr)
  432. break;
  433. __list_add(&line->list, t->list.prev, &t->list);
  434. }
  435. static u64 pblk_line_emeta_start(struct pblk *pblk, struct pblk_line *line)
  436. {
  437. struct nvm_tgt_dev *dev = pblk->dev;
  438. struct nvm_geo *geo = &dev->geo;
  439. struct pblk_line_meta *lm = &pblk->lm;
  440. unsigned int emeta_secs;
  441. u64 emeta_start;
  442. struct ppa_addr ppa;
  443. int pos;
  444. emeta_secs = lm->emeta_sec[0];
  445. emeta_start = lm->sec_per_line;
  446. while (emeta_secs) {
  447. emeta_start--;
  448. ppa = addr_to_gen_ppa(pblk, emeta_start, line->id);
  449. pos = pblk_ppa_to_pos(geo, ppa);
  450. if (!test_bit(pos, line->blk_bitmap))
  451. emeta_secs--;
  452. }
  453. return emeta_start;
  454. }
  455. static int pblk_recov_check_line_version(struct pblk *pblk,
  456. struct line_emeta *emeta)
  457. {
  458. struct line_header *header = &emeta->header;
  459. if (header->version_major != EMETA_VERSION_MAJOR) {
  460. pblk_err(pblk, "line major version mismatch: %d, expected: %d\n",
  461. header->version_major, EMETA_VERSION_MAJOR);
  462. return 1;
  463. }
  464. #ifdef CONFIG_NVM_PBLK_DEBUG
  465. if (header->version_minor > EMETA_VERSION_MINOR)
  466. pblk_info(pblk, "newer line minor version found: %d\n",
  467. header->version_minor);
  468. #endif
  469. return 0;
  470. }
  471. static void pblk_recov_wa_counters(struct pblk *pblk,
  472. struct line_emeta *emeta)
  473. {
  474. struct pblk_line_meta *lm = &pblk->lm;
  475. struct line_header *header = &emeta->header;
  476. struct wa_counters *wa = emeta_to_wa(lm, emeta);
  477. /* WA counters were introduced in emeta version 0.2 */
  478. if (header->version_major > 0 || header->version_minor >= 2) {
  479. u64 user = le64_to_cpu(wa->user);
  480. u64 pad = le64_to_cpu(wa->pad);
  481. u64 gc = le64_to_cpu(wa->gc);
  482. atomic64_set(&pblk->user_wa, user);
  483. atomic64_set(&pblk->pad_wa, pad);
  484. atomic64_set(&pblk->gc_wa, gc);
  485. pblk->user_rst_wa = user;
  486. pblk->pad_rst_wa = pad;
  487. pblk->gc_rst_wa = gc;
  488. }
  489. }
  490. static int pblk_line_was_written(struct pblk_line *line,
  491. struct pblk *pblk)
  492. {
  493. struct pblk_line_meta *lm = &pblk->lm;
  494. struct nvm_tgt_dev *dev = pblk->dev;
  495. struct nvm_geo *geo = &dev->geo;
  496. struct nvm_chk_meta *chunk;
  497. struct ppa_addr bppa;
  498. int smeta_blk;
  499. if (line->state == PBLK_LINESTATE_BAD)
  500. return 0;
  501. smeta_blk = find_first_zero_bit(line->blk_bitmap, lm->blk_per_line);
  502. if (smeta_blk >= lm->blk_per_line)
  503. return 0;
  504. bppa = pblk->luns[smeta_blk].bppa;
  505. chunk = &line->chks[pblk_ppa_to_pos(geo, bppa)];
  506. if (chunk->state & NVM_CHK_ST_CLOSED ||
  507. (chunk->state & NVM_CHK_ST_OPEN
  508. && chunk->wp >= lm->smeta_sec))
  509. return 1;
  510. return 0;
  511. }
  512. static bool pblk_line_is_open(struct pblk *pblk, struct pblk_line *line)
  513. {
  514. struct pblk_line_meta *lm = &pblk->lm;
  515. int i;
  516. for (i = 0; i < lm->blk_per_line; i++)
  517. if (line->chks[i].state & NVM_CHK_ST_OPEN)
  518. return true;
  519. return false;
  520. }
  521. struct pblk_line *pblk_recov_l2p(struct pblk *pblk)
  522. {
  523. struct pblk_line_meta *lm = &pblk->lm;
  524. struct pblk_line_mgmt *l_mg = &pblk->l_mg;
  525. struct pblk_line *line, *tline, *data_line = NULL;
  526. struct pblk_smeta *smeta;
  527. struct pblk_emeta *emeta;
  528. struct line_smeta *smeta_buf;
  529. int found_lines = 0, recovered_lines = 0, open_lines = 0;
  530. int is_next = 0;
  531. int meta_line;
  532. int i, valid_uuid = 0;
  533. LIST_HEAD(recov_list);
  534. /* TODO: Implement FTL snapshot */
  535. /* Scan recovery - takes place when FTL snapshot fails */
  536. spin_lock(&l_mg->free_lock);
  537. meta_line = find_first_zero_bit(&l_mg->meta_bitmap, PBLK_DATA_LINES);
  538. set_bit(meta_line, &l_mg->meta_bitmap);
  539. smeta = l_mg->sline_meta[meta_line];
  540. emeta = l_mg->eline_meta[meta_line];
  541. smeta_buf = (struct line_smeta *)smeta;
  542. spin_unlock(&l_mg->free_lock);
  543. /* Order data lines using their sequence number */
  544. for (i = 0; i < l_mg->nr_lines; i++) {
  545. u32 crc;
  546. line = &pblk->lines[i];
  547. memset(smeta, 0, lm->smeta_len);
  548. line->smeta = smeta;
  549. line->lun_bitmap = ((void *)(smeta_buf)) +
  550. sizeof(struct line_smeta);
  551. if (!pblk_line_was_written(line, pblk))
  552. continue;
  553. /* Lines that cannot be read are assumed as not written here */
  554. if (pblk_line_smeta_read(pblk, line))
  555. continue;
  556. crc = pblk_calc_smeta_crc(pblk, smeta_buf);
  557. if (le32_to_cpu(smeta_buf->crc) != crc)
  558. continue;
  559. if (le32_to_cpu(smeta_buf->header.identifier) != PBLK_MAGIC)
  560. continue;
  561. if (smeta_buf->header.version_major != SMETA_VERSION_MAJOR) {
  562. pblk_err(pblk, "found incompatible line version %u\n",
  563. smeta_buf->header.version_major);
  564. return ERR_PTR(-EINVAL);
  565. }
  566. /* The first valid instance uuid is used for initialization */
  567. if (!valid_uuid) {
  568. guid_copy(&pblk->instance_uuid,
  569. (guid_t *)&smeta_buf->header.uuid);
  570. valid_uuid = 1;
  571. }
  572. if (!guid_equal(&pblk->instance_uuid,
  573. (guid_t *)&smeta_buf->header.uuid)) {
  574. pblk_debug(pblk, "ignore line %u due to uuid mismatch\n",
  575. i);
  576. continue;
  577. }
  578. /* Update line metadata */
  579. spin_lock(&line->lock);
  580. line->id = le32_to_cpu(smeta_buf->header.id);
  581. line->type = le16_to_cpu(smeta_buf->header.type);
  582. line->seq_nr = le64_to_cpu(smeta_buf->seq_nr);
  583. spin_unlock(&line->lock);
  584. /* Update general metadata */
  585. spin_lock(&l_mg->free_lock);
  586. if (line->seq_nr >= l_mg->d_seq_nr)
  587. l_mg->d_seq_nr = line->seq_nr + 1;
  588. l_mg->nr_free_lines--;
  589. spin_unlock(&l_mg->free_lock);
  590. if (pblk_line_recov_alloc(pblk, line))
  591. goto out;
  592. pblk_recov_line_add_ordered(&recov_list, line);
  593. found_lines++;
  594. pblk_debug(pblk, "recovering data line %d, seq:%llu\n",
  595. line->id, smeta_buf->seq_nr);
  596. }
  597. if (!found_lines) {
  598. guid_gen(&pblk->instance_uuid);
  599. spin_lock(&l_mg->free_lock);
  600. WARN_ON_ONCE(!test_and_clear_bit(meta_line,
  601. &l_mg->meta_bitmap));
  602. spin_unlock(&l_mg->free_lock);
  603. goto out;
  604. }
  605. /* Verify closed blocks and recover this portion of L2P table*/
  606. list_for_each_entry_safe(line, tline, &recov_list, list) {
  607. recovered_lines++;
  608. line->emeta_ssec = pblk_line_emeta_start(pblk, line);
  609. line->emeta = emeta;
  610. memset(line->emeta->buf, 0, lm->emeta_len[0]);
  611. if (pblk_line_is_open(pblk, line)) {
  612. pblk_recov_l2p_from_oob(pblk, line);
  613. goto next;
  614. }
  615. if (pblk_line_emeta_read(pblk, line, line->emeta->buf)) {
  616. pblk_recov_l2p_from_oob(pblk, line);
  617. goto next;
  618. }
  619. if (pblk_recov_check_emeta(pblk, line->emeta->buf)) {
  620. pblk_recov_l2p_from_oob(pblk, line);
  621. goto next;
  622. }
  623. if (pblk_recov_check_line_version(pblk, line->emeta->buf))
  624. return ERR_PTR(-EINVAL);
  625. pblk_recov_wa_counters(pblk, line->emeta->buf);
  626. if (pblk_recov_l2p_from_emeta(pblk, line))
  627. pblk_recov_l2p_from_oob(pblk, line);
  628. next:
  629. if (pblk_line_is_full(line)) {
  630. struct list_head *move_list;
  631. spin_lock(&line->lock);
  632. line->state = PBLK_LINESTATE_CLOSED;
  633. trace_pblk_line_state(pblk_disk_name(pblk), line->id,
  634. line->state);
  635. move_list = pblk_line_gc_list(pblk, line);
  636. spin_unlock(&line->lock);
  637. spin_lock(&l_mg->gc_lock);
  638. list_move_tail(&line->list, move_list);
  639. spin_unlock(&l_mg->gc_lock);
  640. mempool_free(line->map_bitmap, l_mg->bitmap_pool);
  641. line->map_bitmap = NULL;
  642. line->smeta = NULL;
  643. line->emeta = NULL;
  644. } else {
  645. spin_lock(&line->lock);
  646. line->state = PBLK_LINESTATE_OPEN;
  647. spin_unlock(&line->lock);
  648. line->emeta->mem = 0;
  649. atomic_set(&line->emeta->sync, 0);
  650. trace_pblk_line_state(pblk_disk_name(pblk), line->id,
  651. line->state);
  652. data_line = line;
  653. line->meta_line = meta_line;
  654. open_lines++;
  655. }
  656. }
  657. if (!open_lines) {
  658. spin_lock(&l_mg->free_lock);
  659. WARN_ON_ONCE(!test_and_clear_bit(meta_line,
  660. &l_mg->meta_bitmap));
  661. spin_unlock(&l_mg->free_lock);
  662. } else {
  663. spin_lock(&l_mg->free_lock);
  664. l_mg->data_line = data_line;
  665. /* Allocate next line for preparation */
  666. l_mg->data_next = pblk_line_get(pblk);
  667. if (l_mg->data_next) {
  668. l_mg->data_next->seq_nr = l_mg->d_seq_nr++;
  669. l_mg->data_next->type = PBLK_LINETYPE_DATA;
  670. is_next = 1;
  671. }
  672. spin_unlock(&l_mg->free_lock);
  673. }
  674. if (is_next)
  675. pblk_line_erase(pblk, l_mg->data_next);
  676. out:
  677. if (found_lines != recovered_lines)
  678. pblk_err(pblk, "failed to recover all found lines %d/%d\n",
  679. found_lines, recovered_lines);
  680. return data_line;
  681. }
  682. /*
  683. * Pad current line
  684. */
  685. int pblk_recov_pad(struct pblk *pblk)
  686. {
  687. struct pblk_line *line;
  688. struct pblk_line_mgmt *l_mg = &pblk->l_mg;
  689. int left_msecs;
  690. int ret = 0;
  691. spin_lock(&l_mg->free_lock);
  692. line = l_mg->data_line;
  693. left_msecs = line->left_msecs;
  694. spin_unlock(&l_mg->free_lock);
  695. ret = pblk_recov_pad_line(pblk, line, left_msecs);
  696. if (ret) {
  697. pblk_err(pblk, "tear down padding failed (%d)\n", ret);
  698. return ret;
  699. }
  700. pblk_line_close_meta(pblk, line);
  701. return ret;
  702. }