int UPDATE_NEW_PAGE_MAPPING(int32_t lpn, int32_t ppn) { /* Update Page Mapping Table */ #ifdef FTL_MAP_CACHE CACHE_UPDATE_PPN(lpn, ppn); #else mapping_table[lpn] = ppn; #endif /* Update Inverse Page Mapping Table */ UPDATE_BLOCK_STATE_ENTRY(CALC_FLASH(ppn), CALC_BLOCK(ppn), CALC_PAGE(ppn), VALID); UPDATE_BLOCK_STATE(CALC_FLASH(ppn), CALC_BLOCK(ppn), DATA_BLOCK); UPDATE_INVERSE_MAPPING(ppn, lpn); return SUCCESS; }
int UPDATE_NEW_PAGE_MAPPING(IDEState *s, int32_t lpn, int32_t ppn) { SSDState *ssd = &(s->ssd); /* Update Page Mapping Table */ #ifdef FTL_MAP_CACHE CACHE_UPDATE_PPN(s, lpn, ppn); #else ssd->mapping_table[lpn] = ppn; #endif /* Update Inverse Page Mapping Table */ UPDATE_BLOCK_STATE_ENTRY(s, CALC_FLASH(s, ppn), CALC_BLOCK(s, ppn), CALC_PAGE(s, ppn), VALID); UPDATE_BLOCK_STATE(s, CALC_FLASH(s, ppn), CALC_BLOCK(s, ppn), DATA_BLOCK); UPDATE_INVERSE_MAPPING(s, ppn, lpn); return SUCCESS; }
int UPDATE_OLD_PAGE_MAPPING(int32_t lpn) { int32_t old_ppn; #ifdef FTL_MAP_CACHE old_ppn = CACHE_GET_PPN(lpn); #else old_ppn = GET_MAPPING_INFO(lpn); #endif if(old_ppn == -1){ #ifdef FTL_DEBUG printf("[%s] New page \n", __FUNCTION__); #endif return SUCCESS; } else{ UPDATE_BLOCK_STATE_ENTRY(CALC_FLASH(old_ppn), CALC_BLOCK(old_ppn), CALC_PAGE(old_ppn), INVALID); UPDATE_INVERSE_MAPPING(old_ppn, -1); } return SUCCESS; }
int BM_GARBAGE_COLLECTION(int32_t victim_pbn) { #ifdef FTL_DEBUG printf("[%s] Start\n", __FUNCTION__); #endif int32_t new_pbn; int32_t v_pbn; int valid_page_nb; int copy_page_nb=0; block_state_entry* temp_b_s_entry = GET_BLOCK_STATE_ENTRY(victim_pbn); /* If the victim block is not a replacement block */ if(temp_b_s_entry->rp_root_pbn == -1){ v_pbn = victim_pbn; } /* If the victim block is a replacement block */ else{ v_pbn = temp_b_s_entry->rp_root_pbn; } block_state_entry* rp_b_s_entry; block_state_entry* root_b_s_entry = GET_BLOCK_STATE_ENTRY(v_pbn); rp_block_entry* rp_b_entry = root_b_s_entry->rp_head; int n_rp_blocks = root_b_s_entry->rp_count; /* Get logical block number of the victim Block */ int32_t lbn = GET_INVERSE_MAPPING_INFO(v_pbn); if(lbn == -1){ printf("ERROR[%s] It is a replacement block !\n", __FUNCTION__); return -1; } /* If the victim block has no replacement block, */ if(n_rp_blocks == 0){ /* Get new empty block */ GET_NEW_BLOCK(VICTIM_OVERALL, EMPTY_TABLE_ENTRY_NB, &new_pbn); /* Copy the valid pages in the victim block to the new empty block */ copy_page_nb = COPY_VALID_PAGES(v_pbn, new_pbn); SSD_BLOCK_ERASE(CALC_FLASH(v_pbn), CALC_BLOCK(v_pbn)); /* Update block mapping information */ UPDATE_OLD_BLOCK_MAPPING(lbn); UPDATE_NEW_BLOCK_MAPPING(lbn, new_pbn); UPDATE_BLOCK_STATE(v_pbn, EMPTY_BLOCK); INSERT_EMPTY_BLOCK(v_pbn); } else{ /* Get the last replacement block */ if(n_rp_blocks == 1){ rp_b_entry = root_b_s_entry->rp_head; } else if(n_rp_blocks == 2){ rp_b_entry = root_b_s_entry->rp_head->next; } /* Get the valid page number of last(tail) replacement block */ rp_b_s_entry = GET_BLOCK_STATE_ENTRY(rp_b_entry->pbn); valid_page_nb = rp_b_s_entry->valid_page_nb; int n_invalid_pages = COUNT_INVALID_PAGES(rp_b_s_entry); /* If all pages in the block is valid, then */ if(valid_page_nb == PAGE_NB || n_invalid_pages == 0){ if(valid_page_nb != PAGE_NB){ int temp_copy_page_nb; rp_block_entry* target_rp_b_entry; rp_block_entry* first_rp_b_entry; if(n_rp_blocks == 1){ target_rp_b_entry = root_b_s_entry->rp_head; copy_page_nb = COPY_VALID_PAGES(v_pbn, target_rp_b_entry->pbn); } else if(n_rp_blocks == 2){ target_rp_b_entry = root_b_s_entry->rp_head->next; first_rp_b_entry = root_b_s_entry->rp_head; temp_copy_page_nb = COPY_VALID_PAGES(v_pbn, target_rp_b_entry->pbn); copy_page_nb = COPY_VALID_PAGES(first_rp_b_entry->pbn, target_rp_b_entry->pbn); copy_page_nb += temp_copy_page_nb; } } /* Mapping Information Update Start */ new_pbn = rp_b_entry->pbn; /* Update the last rp entry of the last replacement block */ rp_b_s_entry->rp_root_pbn = -1; /* free the last rp entry entry */ free(rp_b_entry); if(n_rp_blocks == 2){ /* Update the root entry of the first replacement block */ temp_b_s_entry = GET_BLOCK_STATE_ENTRY(root_b_s_entry->rp_head->pbn); temp_b_s_entry->rp_root_pbn = -1; /* Get rid of first rp block */ SSD_BLOCK_ERASE(CALC_FLASH(root_b_s_entry->rp_head->pbn), CALC_BLOCK(root_b_s_entry->rp_head->pbn)); UPDATE_BLOCK_STATE(root_b_s_entry->rp_head->pbn, EMPTY_BLOCK); INSERT_EMPTY_BLOCK(root_b_s_entry->rp_head->pbn); /* free first rp block entry */ free(root_b_s_entry->rp_head); } /* Update rp block table */ root_b_s_entry->rp_count = 0; root_b_s_entry->rp_head = NULL; /* Get rid of original block */ SSD_BLOCK_ERASE(CALC_FLASH(v_pbn), CALC_BLOCK(v_pbn)); UPDATE_INVERSE_MAPPING(v_pbn, -1); UPDATE_BLOCK_STATE(v_pbn, EMPTY_BLOCK); INSERT_EMPTY_BLOCK(v_pbn); /* Update mapping metadata */ UPDATE_NEW_BLOCK_MAPPING(lbn, new_pbn); } else{ /* Get new empty block */ GET_NEW_BLOCK(VICTIM_OVERALL, EMPTY_TABLE_ENTRY_NB, &new_pbn); /* Copy the valid pages to new empty block */ copy_page_nb = MERGE_RP_BLOCKS(v_pbn, new_pbn); /* Update Block Mapping Information */ UPDATE_OLD_BLOCK_MAPPING(lbn); UPDATE_NEW_BLOCK_MAPPING(lbn, new_pbn); } } #ifdef FTL_DEBUG printf("[%s] End\n", __FUNCTION__); #endif return copy_page_nb; }