From 434ff5642ff086e1d42479c3c768d3f50db8a1eb Mon Sep 17 00:00:00 2001 From: Fadhil Imam Kurnia Date: Thu, 14 Feb 2019 10:33:40 +0700 Subject: [PATCH 1/9] Finish address translation for raid 0 --- raid.c | 46 +++++++++++++++++++++++++++++++++++++++++++++- raid.h | 14 ++++++++++++-- ssd.c | 4 ++++ 3 files changed, 61 insertions(+), 3 deletions(-) diff --git a/raid.c b/raid.c index 2a0c80b..650c233 100644 --- a/raid.c +++ b/raid.c @@ -33,8 +33,18 @@ struct raid_info* initialize_raid(struct raid_info* raid, struct user_args* uarg raid->connected_ssd[i] = pre_process_page(raid->connected_ssd[i]); } + // set raid block size and stripe size + raid->block_size = ssd_pointer->parameter->subpage_capacity; + raid->stripe_size = RAID_STRIPE_SIZE_BYTE; + raid->stripe_size_block = raid->stripe_size / raid->block_size; + raid->strip_size_block = raid->stripe_size_block / raid->num_disk; + if (raid->stripe_size_block == 0 || raid->strip_size_block == 0) { + printf("--> %u %u %u %u\n", raid->block_size, raid->stripe_size, raid->stripe_size_block, raid->strip_size_block); + printf("Error! wrong stripe size or strip size!\n"); + exit(1); + } + // calculating the maximum lsn for the raid - ssd_pointer = raid->connected_ssd[0]; max_lsn_per_disk = (unsigned int) ssd_pointer->parameter->subpage_page * ssd_pointer->parameter->page_block * ssd_pointer->parameter->block_plane * ssd_pointer->parameter->plane_die * ssd_pointer->parameter->die_chip * ssd_pointer->parameter->chip_num * (1 - ssd_pointer->parameter->overprovide ); raid->max_lsn = max_lsn_per_disk * raid->num_disk; if (raid->raid_type == RAID_5) @@ -132,12 +142,46 @@ struct raid_info* simulate_raid0(struct raid_info* raid) { } printf("%lld %d %d %d %d\n", req_incoming_time, req_device_id, req_lsn, req_size, req_operation); + + // insert request to specific disk + // a single request can be inserted to various disk too ._. + raid_distrubute_request(raid, req_incoming_time, req_lsn, req_size, req_operation); + } return raid; } +// raid_distribute_request will distribute single IO request in raid level +// to IO request in disk level. A single IO request can be multiple IO request +// in disk level. This function return 0 if success and -1 if not. +int raid_distrubute_request(struct raid_info* raid, int64_t req_incoming_time, unsigned int req_lsn, unsigned int req_size, unsigned int req_operation) { + unsigned int disk_id, strip_id, stripe_id, stripe_offset, strip_offset; + int req_size_block = req_size; + + if (raid->raid_type == RAID_0) { + while(req_size_block > 0){ + stripe_id = req_lsn / raid->stripe_size_block; + stripe_offset = req_lsn - (stripe_id * raid->stripe_size_block); + strip_id = stripe_offset / raid->strip_size_block; + strip_offset = stripe_offset % raid->strip_size_block; + disk_id = strip_id; + + // TODO: add this request to ssd queue + printf("--> %u %u %u %u\n", disk_id, stripe_id, strip_id, strip_offset); + + req_size_block = req_size_block - (raid->strip_size_block - strip_offset); + if (req_size_block > 0) { + req_size = req_size_block; + req_lsn = req_lsn + req_size; + } + } + } + + return 0; +} + struct raid_info* simulate_raid5(struct raid_info* raid) { printf("Work in progress for simualting raid 5 ...\n"); diff --git a/raid.h b/raid.h index fd84d67..9cb3539 100644 --- a/raid.h +++ b/raid.h @@ -1,9 +1,11 @@ #include "initialize.h" #define RAID_REQUEST_QUEUE_CAPACITY 10 +#define RAID_STRIPE_SIZE_BYTE 65536 +#define RAID_BLOCK_SIZE_BYTE 512 #define RAID_0 0 #define RAID_5 5 -#define NDISK 4 +#define NDISK 3 struct raid_info* initialize_raid(struct raid_info*, struct user_args*); void free_raid_ssd_and_tracefile(struct raid_info*); @@ -13,9 +15,17 @@ int simulate_raid(struct user_args *); struct raid_info* simulate_raid0(struct raid_info*); struct raid_info* simulate_raid5(struct raid_info*); +int raid_distrubute_request(struct raid_info*, int64_t, unsigned int, unsigned int, unsigned int); + +// reference: https://www.snia.org/sites/default/files/SNIA_DDF_Technical_Position_v2.0.pdf +// block and sector is interchangable here struct raid_info { unsigned int raid_type; unsigned int num_disk; + unsigned int block_size; // block size in bytes + unsigned int stripe_size; // stripe size in bytes + unsigned int stripe_size_block; // stripe size in block + unsigned int strip_size_block; // strip size in block char tracefilename[80]; FILE * tracefile; @@ -24,7 +34,7 @@ struct raid_info { unsigned int max_lsn; struct request *request_queue; struct request *request_tail; - int request_queue_length; + unsigned int request_queue_length; struct ssd_info **connected_ssd; }; \ No newline at end of file diff --git a/ssd.c b/ssd.c index 2c9c6b8..aa3b3ef 100644 --- a/ssd.c +++ b/ssd.c @@ -129,6 +129,10 @@ int parse_user_args(int argc, char *argv[], struct user_args* uargs) { printf("Error! RAID simulation requires number of disk (--ndisk)\n"); return -1; } + if (uargs->raid_type == RAID_5 && uargs->num_disk < 3) { + printf("Error! RAID 5 simulation needs at least 3 disks\n"); + return -1; + } if (uargs->is_raid && uargs->num_disk < 2) { printf("Error! RAID simulation needs at least 2 disks\n"); return -1; From 8ccd43b0d5f73c445d4c2925c4dd78e600a0bb07 Mon Sep 17 00:00:00 2001 From: Fadhil Imam Kurnia Date: Thu, 21 Feb 2019 18:29:52 +0700 Subject: [PATCH 2/9] finish insert raid_subreq as request in ssd --- flash.c | 2 - raid.c | 250 ++++++++++++++++++++++++++++++++++++++++++++++++++++---- raid.h | 57 ++++++++++++- ssd.c | 1 - test.c | 2 +- 5 files changed, 291 insertions(+), 21 deletions(-) diff --git a/flash.c b/flash.c index 481bd79..a7d2d31 100644 --- a/flash.c +++ b/flash.c @@ -918,7 +918,6 @@ Status services_2_r_cmd_trans_and_complete(struct ssd_info * ssd) } else if((sub->current_state==SR_COMPLETE)||((sub->next_state==SR_COMPLETE)&&(sub->next_state_predict_time<=ssd->current_time))) { - printf("yap this state\n"); if(sub!=ssd->channel_head[i].subs_r_head) /*if the request is completed, we delete it from read queue */ { p->next_node=sub->next_node; @@ -1639,7 +1638,6 @@ struct ssd_info *process(struct ssd_info *ssd) sub=ssd->channel_head[i].subs_r_head; /*先处理读请求*/ - // TODO: Fadhil, why this function change the flag into 1 services_2_r_wait(ssd,i,&flag,&chg_cur_time_flag); /*处理处于等待状态的读子请求 | Handling read child requests in wait state*/ if((flag==0)&&(ssd->channel_head[i].subs_r_head!=NULL)) /*if there are no new read request and data is ready in some dies, send these data to controller and response this request*/ diff --git a/raid.c b/raid.c index 650c233..aa57a95 100644 --- a/raid.c +++ b/raid.c @@ -13,6 +13,10 @@ struct raid_info* initialize_raid(struct raid_info* raid, struct user_args* uarg raid->num_disk = uargs->num_disk; strcpy(raid->tracefilename, uargs->trace_filename); raid->tracefile = fopen(raid->tracefilename, "r"); + if(raid->tracefile == NULL) { + printf("the tracefile can't be opened\n"); + exit(1); + } raid->connected_ssd=malloc(sizeof(struct ssd_info) * raid->num_disk); alloc_assert(raid->connected_ssd, "connected ssd"); @@ -50,9 +54,41 @@ struct raid_info* initialize_raid(struct raid_info* raid, struct user_args* uarg if (raid->raid_type == RAID_5) raid->max_lsn -= max_lsn_per_disk; + printf("RAID initialized!\n"); + return raid; } +struct raid_request* initialize_raid_request(struct raid_request* raid_req, int64_t req_incoming_time, unsigned int req_lsn, unsigned int req_size, unsigned int req_operation) { + raid_req->begin_time = req_incoming_time; + raid_req->lsn = req_lsn; + raid_req->size = req_size; + raid_req->operation = req_operation; + raid_req->prev_node = NULL; + raid_req->next_node = NULL; + return raid_req; +} + +struct raid_sub_request* initialize_raid_sub_request(struct raid_sub_request* raid_subreq, struct raid_request* raid_req, unsigned int disk_id, unsigned int stripe_id, unsigned int strip_id, unsigned int strip_offset, unsigned int lsn, unsigned int size, unsigned int operation) { + raid_subreq->disk_id = disk_id; + raid_subreq->stripe_id = stripe_id; + raid_subreq->strip_id = strip_id; + raid_subreq->strip_offset = strip_offset; + raid_subreq->begin_time = raid_req->begin_time; + raid_subreq->current_state = R_SR_PENDING; + raid_subreq->lsn = lsn; + raid_subreq->size = size; + raid_subreq->operation = operation; + raid_subreq->next_node = NULL; + if (raid_req->subs == NULL) { + raid_req->subs = raid_subreq; + } else { + raid_req->subs->next_node = raid_subreq; + raid_req->subs = raid_subreq; + } + return raid_subreq; +} + int simulate_raid(struct user_args* uargs) { struct raid_info *raid; @@ -98,13 +134,13 @@ struct raid_info* simulate_raid0(struct raid_info* raid) { char buffer[200]; long filepoint; int64_t req_incoming_time, nearest_event_time; - int req_device_id, req_lsn, req_size, req_operation, flag; + int req_device_id, req_lsn, req_size, req_operation, flag, err; - while (flag != 100) { + while (flag != RAID_SIMULATION_FINISH) { // If we reach the end of the tracefile, stop the simulation if (feof(raid->tracefile)) { - flag = 100; + flag = RAID_SIMULATION_FINISH; } // Read a request from tracefile @@ -114,12 +150,12 @@ struct raid_info* simulate_raid0(struct raid_info* raid) { // Validating incoming request if (req_device_id < 0 || req_lsn < 0 || req_size < 0 || !(req_operation == 0 || req_operation == 1)) { - printf("Error! wrong io request from trace file\n"); - continue; + printf("Error! wrong io request from tracefile (%lld %d %d %d %d)\n", req_incoming_time, req_device_id, req_lsn, req_size, req_operation); + exit(1); } if (req_incoming_time < 0) { - printf("Error! wrong incoming time!\n"); - while(1){} + printf("Error! wrong incoming time! (%lld %d %d %d %d)\n", req_incoming_time, req_device_id, req_lsn, req_size, req_operation); + exit(1); } req_lsn = req_lsn%raid->max_lsn; @@ -143,9 +179,20 @@ struct raid_info* simulate_raid0(struct raid_info* raid) { printf("%lld %d %d %d %d\n", req_incoming_time, req_device_id, req_lsn, req_size, req_operation); - // insert request to specific disk - // a single request can be inserted to various disk too ._. - raid_distrubute_request(raid, req_incoming_time, req_lsn, req_size, req_operation); + // insert request to raid rquest queue + // a single request can be forwarder to multiple disk + err = raid_distribute_request(raid, req_incoming_time, req_lsn, req_size, req_operation); + if (err == R_DIST_ERR) { + fseek(raid->tracefile,filepoint,0); + continue; + } + + // simulate all the ssd in the raid + for(int i = 0; i < raid->num_disk; i++) + raid_simulate_ssd(raid, i); + + // remove processed request from raid queue + raid_clear_completed_request(raid); } @@ -155,21 +202,39 @@ struct raid_info* simulate_raid0(struct raid_info* raid) { // raid_distribute_request will distribute single IO request in raid level // to IO request in disk level. A single IO request can be multiple IO request -// in disk level. This function return 0 if success and -1 if not. -int raid_distrubute_request(struct raid_info* raid, int64_t req_incoming_time, unsigned int req_lsn, unsigned int req_size, unsigned int req_operation) { - unsigned int disk_id, strip_id, stripe_id, stripe_offset, strip_offset; +// in disk level. This function return R_DIST_SUCCESS (0) if success and R_DIST_ERR (1) if not. +int raid_distribute_request(struct raid_info* raid, int64_t req_incoming_time, unsigned int req_lsn, unsigned int req_size, unsigned int req_operation) { + unsigned int disk_id, strip_id, stripe_id, stripe_offset, strip_offset, disk_req_lsn, disk_req_size; int req_size_block = req_size; + struct raid_request* raid_req; + struct raid_sub_request* raid_subreq; if (raid->raid_type == RAID_0) { + + if (raid->request_queue_length == RAID_REQUEST_QUEUE_CAPACITY) { + return R_DIST_ERR; + } + + raid_req = (struct raid_request*)malloc(sizeof(struct raid_request)); + alloc_assert(raid_req, "raid_request"); + memset(raid_req,0,sizeof(struct raid_request)); + initialize_raid_request(raid_req, req_incoming_time, req_lsn, req_size, req_operation); + while(req_size_block > 0){ stripe_id = req_lsn / raid->stripe_size_block; stripe_offset = req_lsn - (stripe_id * raid->stripe_size_block); strip_id = stripe_offset / raid->strip_size_block; strip_offset = stripe_offset % raid->strip_size_block; disk_id = strip_id; + disk_req_lsn = (stripe_id * raid->strip_size_block) + strip_offset; + disk_req_size = (raid->strip_size_block - strip_offset >= req_size) ? raid->strip_size_block - strip_offset : req_size; - // TODO: add this request to ssd queue + // add sub_request to request printf("--> %u %u %u %u\n", disk_id, stripe_id, strip_id, strip_offset); + raid_subreq = (struct raid_sub_request*)malloc(sizeof(struct raid_sub_request)); + alloc_assert(raid_subreq, "raid_sub_request"); + memset(raid_subreq,0,sizeof(struct raid_sub_request)); + initialize_raid_sub_request(raid_subreq, raid_req, disk_id, stripe_id, strip_id, strip_offset, disk_req_lsn, disk_req_size, req_operation); req_size_block = req_size_block - (raid->strip_size_block - strip_offset); if (req_size_block > 0) { @@ -177,11 +242,168 @@ int raid_distrubute_request(struct raid_info* raid, int64_t req_incoming_time, u req_lsn = req_lsn + req_size; } } + + // add request to raid request queue + if (raid->request_queue == NULL) { + raid->request_queue = raid_req; + raid->request_tail = raid->request_queue; + raid->request_queue_length++; + } else { + raid_req->prev_node = raid->request_tail; + raid->request_tail->next_node = raid_req; + raid->request_tail = raid_req; + raid->request_queue_length++; + } } + return R_DIST_SUCCESS; +} + +int raid_clear_completed_request(struct raid_info* raid) { + struct raid_request* req_pointer, *temp_r; + struct raid_sub_request* subreq_pointer, *temp_sr; + int is_all_completed = 1; + + req_pointer = raid->request_queue; + while (req_pointer != NULL){ + is_all_completed = 1; + subreq_pointer = req_pointer->subs; + while (subreq_pointer != NULL){ + if (subreq_pointer->current_state != R_SR_COMPLETE) is_all_completed = 0; + subreq_pointer = subreq_pointer->next_node; + } + + if (is_all_completed) { + subreq_pointer = req_pointer->subs; + while (subreq_pointer != NULL){ + temp_sr = subreq_pointer; + subreq_pointer = temp_sr->next_node; + free(temp_sr); + } + + if (raid->request_queue == req_pointer) { // first element in queue + raid->request_queue = req_pointer->next_node; + free(req_pointer); + req_pointer = raid->request_queue; + } else { + temp_r = req_pointer->prev_node; + req_pointer->prev_node->next_node = req_pointer->next_node; + free(req_pointer); + req_pointer = temp_r; + } + + raid->request_queue_length -= 1; + } + + if (req_pointer != NULL) + req_pointer = req_pointer->next_node; + } + return 0; } +int raid_simulate_ssd(struct raid_info* raid, int disk_id) { + // iterate raid request queue, find any request for this disk + struct ssd_info* ssd; + struct raid_request* req_pointer; + struct raid_sub_request* subreq_pointer; + int flag = 0, err; + + ssd = raid->connected_ssd[disk_id]; + req_pointer = raid->request_queue; + while(req_pointer != NULL){ + subreq_pointer = req_pointer->subs; + while(subreq_pointer != NULL){ + if (subreq_pointer->disk_id == disk_id && subreq_pointer->current_state == R_SR_PENDING) { + // insert to ssd queue + err = raid_ssd_interface(ssd, subreq_pointer); + if (err != ERROR) subreq_pointer->current_state = R_SR_PROCESS; + } + subreq_pointer = subreq_pointer->next_node; + } + req_pointer = req_pointer->next_node; + } + + if (err != ERROR) { + if (ssd->parameter->dram_capacity!=0) { + buffer_management(ssd); + distribute(ssd); + } else { + no_buffer_distribute(ssd); + } + } + + process(ssd); + raid_ssd_trace_output(ssd); + + return 0; +} + +int raid_ssd_interface(struct ssd_info* ssd, struct raid_sub_request *subreq) { + int large_lsn; + int64_t nearest_event_time; + struct request *ssd_request; + + large_lsn = (int)((ssd->parameter->subpage_page*ssd->parameter->page_block*ssd->parameter->block_plane*ssd->parameter->plane_die*ssd->parameter->die_chip*ssd->parameter->chip_num)*(1-ssd->parameter->overprovide)); + subreq->lsn = subreq->lsn % large_lsn; + + nearest_event_time = find_nearest_event(ssd); + if (nearest_event_time == MAX_INT64) { + ssd->current_time = subreq->begin_time; + } else { + if (nearest_event_time < subreq->begin_time) { + if (ssd->current_time <= nearest_event_time) ssd->current_time = nearest_event_time; + return ERROR; + } else { + if (ssd->request_queue_length >= ssd->parameter->queue_length) { + return ERROR; + } else { + ssd->current_time = subreq->begin_time; + } + } + } + + ssd_request = (struct request*) malloc(sizeof(struct request)); + alloc_assert(ssd_request, "ssd_request"); + memset(ssd_request, 0, sizeof(struct request)); + + ssd_request->time = subreq->begin_time; + ssd_request->lsn = subreq->lsn; + ssd_request->size = subreq->size; + ssd_request->operation = subreq->operation; + ssd_request->begin_time = subreq->begin_time; + ssd_request->response_time = 0; + ssd_request->energy_consumption = 0; + ssd_request->next_node = NULL; + ssd_request->distri_flag = 0; + ssd_request->subs = NULL; + ssd_request->need_distr_flag = NULL; + ssd_request->complete_lsn_count=0; + + subreq->req_in_ssd = ssd_request; + + // add to ssd queue + if (ssd->request_queue == NULL) { + ssd->request_queue = ssd_request; + } else { + (ssd->request_tail)->next_node = ssd_request; + } + ssd->request_tail = ssd_request; + ssd->request_queue_length++; + + // update ssd statistics + if (ssd_request->lsn > ssd->max_lsn) ssd->max_lsn = ssd_request->lsn; + if (ssd_request->lsn < ssd->min_lsn) ssd->min_lsn = ssd_request->lsn; + if (ssd_request->operation == WRITE) ssd->ave_write_size=(ssd->ave_write_size*ssd->write_request_count+ssd_request->size)/(ssd->write_request_count+1); + if (ssd_request->operation == READ) ssd->ave_read_size=(ssd->ave_read_size*ssd->read_request_count+request1->size)/(ssd->read_request_count+1); + + return SUCCESS; +} + +int raid_ssd_trace_output(struct ssd_info* ssd) { + trace_output(ssd); + return 0; +} struct raid_info* simulate_raid5(struct raid_info* raid) { printf("Work in progress for simualting raid 5 ...\n"); diff --git a/raid.h b/raid.h index 9cb3539..51e0b57 100644 --- a/raid.h +++ b/raid.h @@ -3,19 +3,37 @@ #define RAID_REQUEST_QUEUE_CAPACITY 10 #define RAID_STRIPE_SIZE_BYTE 65536 #define RAID_BLOCK_SIZE_BYTE 512 +#define RAID_TO_SSD_LATENCY_NS 500000000 #define RAID_0 0 #define RAID_5 5 #define NDISK 3 +#define SSD_SIMULATION_STOP 0 +#define SSD_SIMULATION_CONTINUE 1 +#define RAID_SIMULATION_ERROR 100 +#define RAID_SIMULATION_FINISH 200 +#define R_DIST_ERR 1 +#define R_DIST_SUCCESS 0 + +#define R_SR_PENDING 0 +#define R_SR_PROCESS 1 +#define R_SR_COMPLETE 2 + struct raid_info* initialize_raid(struct raid_info*, struct user_args*); +struct raid_request* initialize_raid_request(struct raid_request* raid_req, int64_t req_incoming_time, unsigned int req_lsn, unsigned int req_size, unsigned int req_operation); +struct raid_sub_request* initialize_raid_sub_request(struct raid_sub_request* raid_subreq, struct raid_request* raid_req, unsigned int disk_id, unsigned int stripe_id, unsigned int strip_id, unsigned int strip_offset, unsigned int lsn, unsigned int size, unsigned int operation); void free_raid_ssd_and_tracefile(struct raid_info*); int64_t raid_find_nearest_event(struct raid_info*); int simulate_raid(struct user_args *); struct raid_info* simulate_raid0(struct raid_info*); struct raid_info* simulate_raid5(struct raid_info*); +int raid_simulate_ssd(struct raid_info*, int); + +int raid_distribute_request(struct raid_info*, int64_t, unsigned int, unsigned int, unsigned int); +int raid_clear_completed_request(struct raid_info*); + -int raid_distrubute_request(struct raid_info*, int64_t, unsigned int, unsigned int, unsigned int); // reference: https://www.snia.org/sites/default/files/SNIA_DDF_Technical_Position_v2.0.pdf // block and sector is interchangable here @@ -32,9 +50,42 @@ struct raid_info { int64_t current_time; unsigned int max_lsn; - struct request *request_queue; - struct request *request_tail; + struct raid_request *request_queue; + struct raid_request *request_tail; unsigned int request_queue_length; struct ssd_info **connected_ssd; +}; + +// Request in RAID level +struct raid_request { + unsigned int lsn; + unsigned int size; + unsigned int operation; + + int64_t begin_time; + int64_t response_time; + + struct raid_sub_request *subs; + struct raid_request *prev_node; + struct raid_request *next_node; +}; + +// Request in SSD level, one raid_request can be separated into multiple raid_sub_request +struct raid_sub_request { + unsigned int disk_id; + unsigned int stripe_id; + unsigned int strip_id; + unsigned int strip_offset; + + int64_t begin_time; + int64_t complete_time; + unsigned int current_state; + + unsigned int lsn; + unsigned int size; + unsigned int operation; + + struct raid_sub_request *next_node; + struct request *req_in_ssd; }; \ No newline at end of file diff --git a/ssd.c b/ssd.c index aa3b3ef..ad624e7 100644 --- a/ssd.c +++ b/ssd.c @@ -227,7 +227,6 @@ struct ssd_info *simulate(struct ssd_info *ssd) // Buffer layer if(flag == 1) { - //printf("once\n"); if (ssd->parameter->dram_capacity!=0) { buffer_management(ssd); diff --git a/test.c b/test.c index 1861a37..d1e230b 100644 --- a/test.c +++ b/test.c @@ -765,7 +765,7 @@ int64_t trace_output(struct ssd_info* ssd){ end_time = 0; if(req == NULL) - return; + return 0; while(req != NULL) { From d95dc180d1e0d212213d0a1dcb5edf8f89fc1cca Mon Sep 17 00:00:00 2001 From: Fadhil Imam Kurnia Date: Wed, 27 Feb 2019 11:12:04 +0700 Subject: [PATCH 3/9] FInish distribute raid request to ssd --- initialize.h | 2 + raid.c | 172 +++++++++++++++++++++++++++++++++++++++++++++++---- raid.h | 7 ++- 3 files changed, 165 insertions(+), 16 deletions(-) diff --git a/initialize.h b/initialize.h index c8fdad8..f87f023 100644 --- a/initialize.h +++ b/initialize.h @@ -384,6 +384,8 @@ struct request{ struct sub_request *subs; //链接到属于该请求的所有子请求 struct request *next_node; //指向下一个请求结构体 + + struct raid_sub_request *subreq_on_raid; }; diff --git a/raid.c b/raid.c index aa57a95..9aaa046 100644 --- a/raid.c +++ b/raid.c @@ -188,9 +188,12 @@ struct raid_info* simulate_raid0(struct raid_info* raid) { } // simulate all the ssd in the raid - for(int i = 0; i < raid->num_disk; i++) + for(int i = 0; i < raid->num_disk; i++) { + printf("simulate disk %d\n", i); raid_simulate_ssd(raid, i); - + printf("end simulate disk %d\n", i); + } + // remove processed request from raid queue raid_clear_completed_request(raid); @@ -230,7 +233,7 @@ int raid_distribute_request(struct raid_info* raid, int64_t req_incoming_time, u disk_req_size = (raid->strip_size_block - strip_offset >= req_size) ? raid->strip_size_block - strip_offset : req_size; // add sub_request to request - printf("--> %u %u %u %u\n", disk_id, stripe_id, strip_id, strip_offset); + printf("--> %u %u %u %u %u\n", disk_id, stripe_id, strip_id, strip_offset, disk_req_lsn); raid_subreq = (struct raid_sub_request*)malloc(sizeof(struct raid_sub_request)); alloc_assert(raid_subreq, "raid_sub_request"); memset(raid_subreq,0,sizeof(struct raid_sub_request)); @@ -282,12 +285,13 @@ int raid_clear_completed_request(struct raid_info* raid) { } if (raid->request_queue == req_pointer) { // first element in queue - raid->request_queue = req_pointer->next_node; + raid->request_queue = NULL; + raid->request_tail = NULL; free(req_pointer); req_pointer = raid->request_queue; } else { temp_r = req_pointer->prev_node; - req_pointer->prev_node->next_node = req_pointer->next_node; + (req_pointer->prev_node)->next_node = req_pointer->next_node; free(req_pointer); req_pointer = temp_r; } @@ -298,7 +302,6 @@ int raid_clear_completed_request(struct raid_info* raid) { if (req_pointer != NULL) req_pointer = req_pointer->next_node; } - return 0; } @@ -323,7 +326,7 @@ int raid_simulate_ssd(struct raid_info* raid, int disk_id) { } req_pointer = req_pointer->next_node; } - + if (err != ERROR) { if (ssd->parameter->dram_capacity!=0) { buffer_management(ssd); @@ -363,6 +366,7 @@ int raid_ssd_interface(struct ssd_info* ssd, struct raid_sub_request *subreq) { } } + ssd_request = (struct request*) malloc(sizeof(struct request)); alloc_assert(ssd_request, "ssd_request"); memset(ssd_request, 0, sizeof(struct request)); @@ -379,8 +383,7 @@ int raid_ssd_interface(struct ssd_info* ssd, struct raid_sub_request *subreq) { ssd_request->subs = NULL; ssd_request->need_distr_flag = NULL; ssd_request->complete_lsn_count=0; - - subreq->req_in_ssd = ssd_request; + ssd_request->subreq_on_raid = subreq; // add to ssd queue if (ssd->request_queue == NULL) { @@ -395,14 +398,157 @@ int raid_ssd_interface(struct ssd_info* ssd, struct raid_sub_request *subreq) { if (ssd_request->lsn > ssd->max_lsn) ssd->max_lsn = ssd_request->lsn; if (ssd_request->lsn < ssd->min_lsn) ssd->min_lsn = ssd_request->lsn; if (ssd_request->operation == WRITE) ssd->ave_write_size=(ssd->ave_write_size*ssd->write_request_count+ssd_request->size)/(ssd->write_request_count+1); - if (ssd_request->operation == READ) ssd->ave_read_size=(ssd->ave_read_size*ssd->read_request_count+request1->size)/(ssd->read_request_count+1); + if (ssd_request->operation == READ) ssd->ave_read_size=(ssd->ave_read_size*ssd->read_request_count+ssd_request->size)/(ssd->read_request_count+1); return SUCCESS; } -int raid_ssd_trace_output(struct ssd_info* ssd) { - trace_output(ssd); - return 0; +void raid_ssd_trace_output(struct ssd_info* ssd) { + struct request *req, *req_temp; + struct sub_request *sub, *tmp; + int64_t start_time, end_time, latency; + int is_all_sub_completed; + + req_temp = NULL; + req = ssd->request_queue; + if (req == NULL) + return; + + while (req != NULL){ + latency = 0; + if (req->response_time != 0) { + latency = req->response_time - req->time; + fprintf(ssd->outputfile,"%16lld %10d %6d %2d %16lld %16lld %10lld %2d %10lld\n",req->time,req->lsn, req->size, req->operation, req->begin_time, req->response_time, latency, req->meet_gc_flag, req->meet_gc_remaining_time); fflush(ssd->outputfile); + fprintf(ssd->outfile_io,"%16lld %10d %6d %2d %16lld %16lld %10lld %2d %10lld\n",req->time,req->lsn, req->size, req->operation, req->begin_time, req->response_time, latency, req->meet_gc_flag, req->meet_gc_remaining_time); fflush(ssd->outfile_io); + if (req->operation == WRITE) { + fprintf(ssd->outfile_io_write,"%16lld %10d %6d %2d %16lld %16lld %10lld %2d %10lld\n",req->time,req->lsn, req->size, req->operation, req->begin_time, req->response_time, latency, req->meet_gc_flag, req->meet_gc_remaining_time); + fflush(ssd->outfile_io_write); + ssd->write_request_count++; + ssd->write_avg=ssd->write_avg+(req->response_time-req->time); + } else if (req->operation == READ){ + fprintf(ssd->outfile_io_read,"%16lld %10d %6d %2d %16lld %16lld %10lld %2d %10lld\n",req->time,req->lsn, req->size, req->operation, req->begin_time, req->response_time, latency, req->meet_gc_flag, req->meet_gc_remaining_time); + fflush(ssd->outfile_io_read); + ssd->read_request_count++; + ssd->read_avg=ssd->read_avg+(req->response_time-req->time); + } + + if(req->response_time-req->begin_time==0) { + printf("the response time is 0?? \n"); + exit(1); + } + + req_temp = req; + req = req->next_node; + ssd_delete_request_from_queue(ssd, req_temp); + + } else { + sub = req->subs; + is_all_sub_completed = 1; + start_time = end_time = 0; + + // if any sub-request is not completed, the request is not completed + while (sub != NULL){ + if (start_time == 0) start_time = sub->begin_time; + if (start_time > sub->begin_time) start_time = sub->begin_time; + if (end_time < sub->complete_time) end_time = sub->complete_time; + + if((sub->current_state == SR_COMPLETE)||((sub->next_state==SR_COMPLETE)&&(sub->next_state_predict_time<=ssd->current_time))) { + sub = sub->next_node; + } else { + is_all_sub_completed = 0; + break; + } + } + + if (is_all_sub_completed) { + latency = end_time-req->time; + + fprintf(ssd->outputfile,"%16lld %10d %6d %2d %16lld %16lld %10lld %2d %10lld\n",req->time,req->lsn, req->size, req->operation, req->begin_time, req->response_time, latency, req->meet_gc_flag, req->meet_gc_remaining_time); + fflush(ssd->outputfile); + fprintf(ssd->outfile_io,"%16lld %10d %6d %2d %16lld %16lld %10lld %2d %10lld\n",req->time,req->lsn, req->size, req->operation, req->begin_time, req->response_time, latency, req->meet_gc_flag, req->meet_gc_remaining_time); + fflush(ssd->outfile_io); + + if (req->operation == WRITE) { + fprintf(ssd->outfile_io_write,"%16lld %10d %6d %2d %16lld %16lld %10lld %2d %10lld\n",req->time,req->lsn, req->size, req->operation, req->begin_time, req->response_time, latency, req->meet_gc_flag, req->meet_gc_remaining_time); + fflush(ssd->outfile_io_write); + ssd->write_request_count++; + ssd->write_avg=ssd->write_avg+(end_time-req->time); + } else if (req->operation == READ){ + fprintf(ssd->outfile_io_read,"%16lld %10d %6d %2d %16lld %16lld %10lld %2d %10lld\n",req->time,req->lsn, req->size, req->operation, req->begin_time, req->response_time, latency, req->meet_gc_flag, req->meet_gc_remaining_time); + fflush(ssd->outfile_io_read); + ssd->read_request_count++; + ssd->read_avg=ssd->read_avg+(end_time-req->time); + } + + if(end_time-start_time==0) { + printf("the response time is 0?? \n"); + exit(1); + } + + // empty the sub on the req + while (req->subs!=NULL){ + tmp = req->subs; + req->subs = tmp->next_subs; + if (tmp->update!=NULL) { + free(tmp->update->location); + tmp->update->location=NULL; + free(tmp->update); + tmp->update=NULL; + } + free(tmp->location); + tmp->location=NULL; + free(tmp); + tmp=NULL; + } + + req_temp = req; + req = req->next_node; + ssd_delete_request_from_queue(ssd, req_temp); + + } else { + req = req->next_node; + } + + } + } + + + return; +} + +void ssd_delete_request_from_queue(struct ssd_info* ssd, struct request *req) { + struct request *temp, *prev; + + if (req == ssd->request_queue) { + (req->subreq_on_raid)->current_state = R_SR_COMPLETE; + (req->subreq_on_raid)->complete_time = req->response_time; + req->subreq_on_raid = NULL; + ssd->request_queue = req->next_node; + + if (req->need_distr_flag != NULL) free(req->need_distr_flag); + free(req); + + ssd->request_queue=NULL; + ssd->request_tail=NULL; + ssd->request_queue_length--; + return; + } + + temp = ssd->request_queue; + while (temp != NULL && temp != req) { + prev = temp; + temp = temp->next_node; + } + + if (temp == NULL) return; + + prev->next_node = temp->next_node; + (req->subreq_on_raid)->current_state = R_SR_COMPLETE; + (req->subreq_on_raid)->complete_time = req->response_time; + if (req->need_distr_flag != NULL) free(req->need_distr_flag); + free(req); + ssd->request_queue_length--; + return; } struct raid_info* simulate_raid5(struct raid_info* raid) { diff --git a/raid.h b/raid.h index 51e0b57..37f414d 100644 --- a/raid.h +++ b/raid.h @@ -1,5 +1,3 @@ -#include "initialize.h" - #define RAID_REQUEST_QUEUE_CAPACITY 10 #define RAID_STRIPE_SIZE_BYTE 65536 #define RAID_BLOCK_SIZE_BYTE 512 @@ -29,10 +27,14 @@ int simulate_raid(struct user_args *); struct raid_info* simulate_raid0(struct raid_info*); struct raid_info* simulate_raid5(struct raid_info*); int raid_simulate_ssd(struct raid_info*, int); +int raid_ssd_interface(struct ssd_info*, struct raid_sub_request*); +void raid_ssd_trace_output(struct ssd_info*); int raid_distribute_request(struct raid_info*, int64_t, unsigned int, unsigned int, unsigned int); int raid_clear_completed_request(struct raid_info*); +void ssd_delete_request_from_queue(struct ssd_info*, struct request*); + // reference: https://www.snia.org/sites/default/files/SNIA_DDF_Technical_Position_v2.0.pdf @@ -87,5 +89,4 @@ struct raid_sub_request { unsigned int operation; struct raid_sub_request *next_node; - struct request *req_in_ssd; }; \ No newline at end of file From 5ce8369e078dd84f9d87e8b1f6e2edb72c199a8e Mon Sep 17 00:00:00 2001 From: Fadhil Imam Kurnia Date: Sat, 23 Mar 2019 14:04:55 +0700 Subject: [PATCH 4/9] raid controller checkpoint, still has a lot of bug, unfunctional --- Makefile | 2 +- flash.c | 9 +- raid.c | 355 +++++++++++++++++++++++++++++++++++++++++++++---------- raid.h | 6 +- ssd.c | 1 + 5 files changed, 300 insertions(+), 73 deletions(-) diff --git a/Makefile b/Makefile index 07e7a39..899ce15 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,7 @@ test.o: flash.h initialize.h pagemap.h gcc -c -g test.c ssd: ssd.o avlTree.o flash.o initialize.o pagemap.o raid.o cc -g -o ssd ssd.o avlTree.o flash.o initialize.o pagemap.o raid.o - rm *.o +# rm *.o ssd.o: flash.h initialize.h pagemap.h raid.h gcc -c -g ssd.c flash.o: pagemap.h diff --git a/flash.c b/flash.c index a7d2d31..56efa5c 100644 --- a/flash.c +++ b/flash.c @@ -704,6 +704,7 @@ struct sub_request * creat_sub_request(struct ssd_info * ssd,unsigned int lpn,in free(sub); sub=NULL; printf("\nERROR ! Unexpected command.\n"); + exit(100); return NULL; } @@ -774,7 +775,7 @@ struct sub_request * find_read_sub_request(struct ssd_info * ssd, unsigned int c } else { - printf("Error! Can't find the sub request."); + printf("Error! Can't find the sub request. [%lld %u]\n", sub->begin_time, sub->operation); } } } @@ -905,7 +906,6 @@ Status services_2_r_cmd_trans_and_complete(struct ssd_info * ssd) for(i=0;iparameter->channel_number;i++) /*这个循环处理不需要channel的时间(读命令已经到达chip,chip由ready变为busy),当读请求完成时,将其从channel的队列中取出*/ { sub=ssd->channel_head[i].subs_r_head; - while(sub!=NULL) { if(sub->current_state==SR_R_C_A_TRANSFER) /*读命令发送完毕,将对应的die置为busy,同时修改sub的状态; 这个部分专门处理读请求由当前状态为传命令变为die开始busy,die开始busy不需要channel为空,所以单独列出*/ @@ -950,7 +950,7 @@ Status services_2_r_cmd_trans_and_complete(struct ssd_info * ssd) Status services_2_r_data_trans(struct ssd_info * ssd,unsigned int channel,unsigned int * channel_busy_flag, unsigned int * change_current_time_flag) { int chip=0; - unsigned int die=0,plane=0,address_ppn=0,die1=0; + unsigned int die=0,plane=0,address_ppn=0,die1=0,sub_plane; struct sub_request * sub=NULL, * p=NULL,*sub1=NULL; struct sub_request * sub_twoplane_one=NULL, * sub_twoplane_two=NULL; struct sub_request * sub_interleave_one=NULL, * sub_interleave_two=NULL; @@ -983,7 +983,7 @@ Status services_2_r_data_trans(struct ssd_info * ssd,unsigned int channel,unsign if ((ssd->parameter->advanced_commands&AD_TWOPLANE_READ)==AD_TWOPLANE_READ) /*有可能产生了two plane操作,在这种情况下,将同一个die上的两个plane的数据依次传出*/ { sub_twoplane_one=sub; - sub_twoplane_two=NULL; + sub_twoplane_two=NULL; /*为了保证找到的sub_twoplane_two与sub_twoplane_one不同,令add_reg_ppn=-1*/ ssd->channel_head[channel].chip_head[chip].die_head[die].plane_head[sub->location->plane].add_reg_ppn=-1; sub_twoplane_two=find_read_sub_request(ssd,channel,chip,die); /*在相同的channel,chip,die中寻找另外一个读子请求*/ @@ -1637,7 +1637,6 @@ struct ssd_info *process(struct ssd_info *ssd) } sub=ssd->channel_head[i].subs_r_head; /*先处理读请求*/ - services_2_r_wait(ssd,i,&flag,&chg_cur_time_flag); /*处理处于等待状态的读子请求 | Handling read child requests in wait state*/ if((flag==0)&&(ssd->channel_head[i].subs_r_head!=NULL)) /*if there are no new read request and data is ready in some dies, send these data to controller and response this request*/ diff --git a/raid.c b/raid.c index 9aaa046..1a2e9c9 100644 --- a/raid.c +++ b/raid.c @@ -130,74 +130,152 @@ int64_t raid_find_nearest_event(struct raid_info* raid) { return nearest_time; } -struct raid_info* simulate_raid0(struct raid_info* raid) { - char buffer[200]; +void break_raid0_tracefile(struct raid_info* raid) { long filepoint; + char buffer[200]; int64_t req_incoming_time, nearest_event_time; - int req_device_id, req_lsn, req_size, req_operation, flag, err; - - while (flag != RAID_SIMULATION_FINISH) { - - // If we reach the end of the tracefile, stop the simulation - if (feof(raid->tracefile)) { - flag = RAID_SIMULATION_FINISH; + int req_device_id, req_lsn, req_size, req_operation, flag, err, is_accept_req; + unsigned int disk_id, strip_id, stripe_id, stripe_offset, strip_offset, disk_req_lsn, disk_req_size; + int req_size_block; + + FILE **tracefile; + tracefile = malloc(sizeof(FILE*) * raid->num_disk); + for(int i=0; i < raid->num_disk; i++) { + sprintf(buffer, "raid0disk%d.trace", i); + tracefile[i] = fopen(buffer, "w"); + if(tracefile[i] == NULL) { + printf("the %d tracefile can't be opened\n", i); + exit(1); } - - // Read a request from tracefile + } + + while (!feof(raid->tracefile)) { filepoint = ftell(raid->tracefile); fgets (buffer, 200, raid->tracefile); sscanf (buffer,"%lld %d %d %d %d", &req_incoming_time, &req_device_id, &req_lsn, &req_size, &req_operation); - // Validating incoming request - if (req_device_id < 0 || req_lsn < 0 || req_size < 0 || !(req_operation == 0 || req_operation == 1)) { - printf("Error! wrong io request from tracefile (%lld %d %d %d %d)\n", req_incoming_time, req_device_id, req_lsn, req_size, req_operation); - exit(1); + printf("%lld %d %d %d %d\n", req_incoming_time, req_device_id, req_lsn, req_size, req_operation); + req_size_block = req_size; + + while(req_size_block > 0){ + stripe_id = req_lsn / raid->stripe_size_block; + stripe_offset = req_lsn - (stripe_id * raid->stripe_size_block); + strip_id = stripe_offset / raid->strip_size_block; + strip_offset = stripe_offset % raid->strip_size_block; + disk_id = strip_id; + disk_req_lsn = (stripe_id * raid->strip_size_block) + strip_offset; + disk_req_size = (raid->strip_size_block - strip_offset >= req_size) ? raid->strip_size_block - strip_offset : req_size; + + // add sub_request to request + printf(" ---> req distributed to ssd: %u %u %u %u %u\n", disk_id, stripe_id, strip_id, strip_offset, disk_req_lsn); + fprintf(tracefile[disk_id], "%lld 0 %u %u %u\n", req_incoming_time, disk_req_lsn, disk_req_size, req_operation); + + req_size_block = req_size_block - (raid->strip_size_block - strip_offset); + if (req_size_block > 0) { + req_size = req_size_block; + req_lsn = req_lsn + req_size; + } } - if (req_incoming_time < 0) { - printf("Error! wrong incoming time! (%lld %d %d %d %d)\n", req_incoming_time, req_device_id, req_lsn, req_size, req_operation); - exit(1); + + } + + for(int i=0; i < raid->num_disk; i++) { + fclose(tracefile[i]); + } +} + +struct raid_info* simulate_raid0(struct raid_info* raid) { + int req_device_id, req_lsn, req_size, req_operation, flag, err, is_accept_req, interface_flag; + int64_t req_incoming_time, nearest_event_time; + struct ssd_info *ssd; + char buffer[200]; + long filepoint; + + while (flag != RAID_SIMULATION_FINISH) { + + // Stop the simulation, if we reach the end of the tracefile and request queue is empty + if (feof(raid->tracefile) && raid->request_queue_length==0) { + flag = RAID_SIMULATION_FINISH; } - req_lsn = req_lsn%raid->max_lsn; - // Set raid current_time - nearest_event_time = raid_find_nearest_event(raid); - if (nearest_event_time == MAX_INT64) { - raid->current_time = req_incoming_time; - } else if (nearest_event_time < req_incoming_time){ - fseek(raid->tracefile,filepoint,0); - raid->current_time = nearest_event_time; - continue; - } else { + if (!feof(raid->tracefile)) { + + // Read a request from tracefile + filepoint = ftell(raid->tracefile); + fgets (buffer, 200, raid->tracefile); + sscanf (buffer,"%lld %d %d %d %d", &req_incoming_time, &req_device_id, &req_lsn, &req_size, &req_operation); + is_accept_req = 1; + + // Validating incoming request + if (req_device_id < 0 || req_lsn < 0 || req_size < 0 || !(req_operation == 0 || req_operation == 1)) { + printf("Error! wrong io request from tracefile (%lld %d %d %d %d)\n", req_incoming_time, req_device_id, req_lsn, req_size, req_operation); + exit(1); + } + if (req_incoming_time < 0) { + printf("Error! wrong incoming time! (%lld %d %d %d %d)\n", req_incoming_time, req_device_id, req_lsn, req_size, req_operation); + exit(1); + } + req_lsn = req_lsn%raid->max_lsn; + + // if nearest event time is less than incoming time, than skip to insert this request + // if queue is full, skip this request too + // Set raid current_time + + // Check whether we can process this request or not, also set raid->current_time + nearest_event_time = raid_find_nearest_event(raid); + printf(" nearest time %lld %lld %lld %d\n", nearest_event_time, req_incoming_time, raid->current_time, raid->request_queue_length); if (raid->request_queue_length >= RAID_REQUEST_QUEUE_CAPACITY) { fseek(raid->tracefile,filepoint,0); raid->current_time = nearest_event_time; - continue; - } else { - raid->current_time = req_incoming_time; + is_accept_req = 0; } - } - printf("%lld %d %d %d %d\n", req_incoming_time, req_device_id, req_lsn, req_size, req_operation); - - // insert request to raid rquest queue - // a single request can be forwarder to multiple disk - err = raid_distribute_request(raid, req_incoming_time, req_lsn, req_size, req_operation); - if (err == R_DIST_ERR) { - fseek(raid->tracefile,filepoint,0); - continue; + if (is_accept_req) { + printf("req inserted: %lld %d %d %d %d [%d]\n", req_incoming_time, req_device_id, req_lsn, req_size, req_operation, raid->request_queue_length); + + // insert request to raid rquest queue + // a single request can be forwarder to multiple disk + err = raid_distribute_request(raid, req_incoming_time, req_lsn, req_size, req_operation); + if (err == R_DIST_ERR) { + fseek(raid->tracefile,filepoint,0); + printf("Error! Distributing raid request failed!\n"); + // getchar(); + continue; + } + } } - // simulate all the ssd in the raid + // simulate all the ssd in the raid, + // this is corresponding to simulate(ssd_info *ssd) function in ssd.c for(int i = 0; i < raid->num_disk; i++) { - printf("simulate disk %d\n", i); - raid_simulate_ssd(raid, i); - printf("end simulate disk %d\n", i); + printf("begin simulating disk %d\n", i); + // raid_simulate_ssd(raid, i); + + ssd = raid->connected_ssd[i]; + + // Interface layer + interface_flag = raid_ssd_get_requests(i, ssd, raid); + + // Buffer layer + if(interface_flag == 1) { + if (ssd->parameter->dram_capacity!=0) { + buffer_management(ssd); + distribute(ssd); + } else { + no_buffer_distribute(ssd); + } + } + + // FTL+FCL+Flash layer + process(ssd); + raid_ssd_trace_output(ssd); + + printf("end simulating disk %d\n", i); } // remove processed request from raid queue raid_clear_completed_request(raid); - } return raid; @@ -233,7 +311,7 @@ int raid_distribute_request(struct raid_info* raid, int64_t req_incoming_time, u disk_req_size = (raid->strip_size_block - strip_offset >= req_size) ? raid->strip_size_block - strip_offset : req_size; // add sub_request to request - printf("--> %u %u %u %u %u\n", disk_id, stripe_id, strip_id, strip_offset, disk_req_lsn); + printf("--> req distributed to ssd: %u %u %u %u %u\n", disk_id, stripe_id, strip_id, strip_offset, disk_req_lsn); raid_subreq = (struct raid_sub_request*)malloc(sizeof(struct raid_sub_request)); alloc_assert(raid_subreq, "raid_sub_request"); memset(raid_subreq,0,sizeof(struct raid_sub_request)); @@ -250,13 +328,12 @@ int raid_distribute_request(struct raid_info* raid, int64_t req_incoming_time, u if (raid->request_queue == NULL) { raid->request_queue = raid_req; raid->request_tail = raid->request_queue; - raid->request_queue_length++; } else { raid_req->prev_node = raid->request_tail; raid->request_tail->next_node = raid_req; raid->request_tail = raid_req; - raid->request_queue_length++; } + raid->request_queue_length++; } return R_DIST_SUCCESS; @@ -265,18 +342,21 @@ int raid_distribute_request(struct raid_info* raid, int64_t req_incoming_time, u int raid_clear_completed_request(struct raid_info* raid) { struct raid_request* req_pointer, *temp_r; struct raid_sub_request* subreq_pointer, *temp_sr; - int is_all_completed = 1; + int is_all_completed = 1, is_need_move_forward = 1; req_pointer = raid->request_queue; while (req_pointer != NULL){ - is_all_completed = 1; + printf(" [x] %lld\n", req_pointer->begin_time); + is_all_completed = is_need_move_forward = 1; subreq_pointer = req_pointer->subs; while (subreq_pointer != NULL){ + printf(" [-] %d %d %lld\n", subreq_pointer->disk_id, subreq_pointer->current_state, subreq_pointer->begin_time); if (subreq_pointer->current_state != R_SR_COMPLETE) is_all_completed = 0; subreq_pointer = subreq_pointer->next_node; } if (is_all_completed) { + printf(">>>>>> deleting req : %lld [%d]\n", req_pointer->begin_time, raid->request_queue_length); subreq_pointer = req_pointer->subs; while (subreq_pointer != NULL){ temp_sr = subreq_pointer; @@ -284,14 +364,25 @@ int raid_clear_completed_request(struct raid_info* raid) { free(temp_sr); } - if (raid->request_queue == req_pointer) { // first element in queue - raid->request_queue = NULL; - raid->request_tail = NULL; + if (raid->request_queue_length == 1) { // the only element in queue + free(req_pointer); + req_pointer = NULL; + raid->request_queue = raid->request_tail = NULL; + is_need_move_forward = 0; + } else if (raid->request_queue == req_pointer) { // first element in queue with multiple elements + raid->request_queue = req_pointer->next_node; + raid->request_queue->prev_node = NULL; free(req_pointer); req_pointer = raid->request_queue; - } else { + is_need_move_forward = 0; + } else { // middle or last element in queue temp_r = req_pointer->prev_node; - (req_pointer->prev_node)->next_node = req_pointer->next_node; + temp_r->next_node = req_pointer->next_node; + if (raid->request_tail == req_pointer) { + raid->request_tail = req_pointer->prev_node; + } else { + (req_pointer->next_node)->prev_node = temp_r; + } free(req_pointer); req_pointer = temp_r; } @@ -299,26 +390,27 @@ int raid_clear_completed_request(struct raid_info* raid) { raid->request_queue_length -= 1; } - if (req_pointer != NULL) + if (req_pointer != NULL && is_need_move_forward) req_pointer = req_pointer->next_node; } return 0; } int raid_simulate_ssd(struct raid_info* raid, int disk_id) { - // iterate raid request queue, find any request for this disk + // iterate raid request queue, find first incoming request for this disk struct ssd_info* ssd; struct raid_request* req_pointer; struct raid_sub_request* subreq_pointer; - int flag = 0, err; + int flag = 0, err = ERROR, is_found=0; ssd = raid->connected_ssd[disk_id]; req_pointer = raid->request_queue; - while(req_pointer != NULL){ + while(req_pointer != NULL && !is_found){ subreq_pointer = req_pointer->subs; - while(subreq_pointer != NULL){ + while(subreq_pointer != NULL && !is_found){ if (subreq_pointer->disk_id == disk_id && subreq_pointer->current_state == R_SR_PENDING) { - // insert to ssd queue + is_found = 1; + // insert to ssd queue err = raid_ssd_interface(ssd, subreq_pointer); if (err != ERROR) subreq_pointer->current_state = R_SR_PROCESS; } @@ -328,8 +420,9 @@ int raid_simulate_ssd(struct raid_info* raid, int disk_id) { } if (err != ERROR) { + printf(">>>>> Req inserted to ssd queue %lld!\n", ssd->request_tail->begin_time); if (ssd->parameter->dram_capacity!=0) { - buffer_management(ssd); + buffer_management(ssd);; distribute(ssd); } else { no_buffer_distribute(ssd); @@ -342,15 +435,126 @@ int raid_simulate_ssd(struct raid_info* raid, int disk_id) { return 0; } +int raid_ssd_get_requests(int disk_id, struct ssd_info *ssd, struct raid_info *raid) { + struct raid_request *rreq; + struct raid_sub_request *rsreq; + struct request *ssd_request; + int is_found = 0; + + unsigned int req_lsn=0; + int req_device, req_size, req_ope, large_lsn; + int64_t req_time = 0; + int64_t nearest_event_time; + + rreq = raid->request_queue; + + // get request for this disk from raid req queue + while (rreq != NULL && !is_found) { + rsreq = rreq->subs; + while (rsreq != NULL) { + if (rsreq->disk_id == disk_id && rsreq->current_state == R_SR_PENDING) { + is_found = 1; + break; + } + rsreq = rsreq->next_node; + } + rreq = rreq->next_node; + } + + // no request for this disk + if (rsreq == NULL) return 0; + + // insert this request to requst queue in ssd + req_device = disk_id; + req_time = rsreq->begin_time; + req_lsn = rsreq->lsn; + req_size = rsreq->size; + req_ope = rsreq->operation; + + if (req_device < 0 || req_size < 0 || req_lsn < 0 || req_ope < 0) { + printf("Error! wrong io request from raid controller\n"); + exit(100); + } + + large_lsn=(int)((ssd->parameter->subpage_page*ssd->parameter->page_block*ssd->parameter->block_plane*ssd->parameter->plane_die*ssd->parameter->die_chip*ssd->parameter->chip_num)*(1-ssd->parameter->overprovide)); + req_lsn = req_lsn%large_lsn; + nearest_event_time=find_nearest_event(ssd); + + if (nearest_event_time==MAX_INT64) { + ssd->current_time = req_time; + } else { + if (nearest_event_time < req_time) { + if (ssd->current_time <= nearest_event_time) ssd->current_time = nearest_event_time; + return -1; + } else { + if (ssd->request_queue_length>=ssd->parameter->queue_length) { + ssd->current_time = nearest_event_time; + return -1; + } else { + ssd->current_time = req_time; + } + } + } + + if (req_time < 0) { + printf("Error! wrong io request's incoming time\n"); + exit(100); + } + + ssd_request = (struct request*) malloc(sizeof(struct request)); + alloc_assert(ssd_request, "ssd_request"); + memset(ssd_request, 0, sizeof(struct request)); + + ssd_request->time = req_time; + ssd_request->lsn = req_lsn; + ssd_request->size = req_size; + ssd_request->operation = req_ope; + ssd_request->begin_time = req_time; + ssd_request->response_time = 0; + ssd_request->energy_consumption = 0; + ssd_request->next_node = NULL; + ssd_request->distri_flag = 0; + ssd_request->subs = NULL; + ssd_request->need_distr_flag = NULL; + ssd_request->complete_lsn_count=0; + ssd_request->subreq_on_raid = rsreq; + + // add to ssd queue + if (ssd->request_queue == NULL) { + ssd->request_queue = ssd_request; + } else { + (ssd->request_tail)->next_node = ssd_request; + } + ssd->request_tail = ssd_request; + ssd->request_queue_length++; + + // update ssd statistics + if (ssd_request->lsn > ssd->max_lsn) ssd->max_lsn = ssd_request->lsn; + if (ssd_request->lsn < ssd->min_lsn) ssd->min_lsn = ssd_request->lsn; + if (ssd_request->operation == WRITE) ssd->ave_write_size=(ssd->ave_write_size*ssd->write_request_count+ssd_request->size)/(ssd->write_request_count+1); + if (ssd_request->operation == READ) ssd->ave_read_size=(ssd->ave_read_size*ssd->read_request_count+ssd_request->size)/(ssd->read_request_count+1); + + return 1; +} + int raid_ssd_interface(struct ssd_info* ssd, struct raid_sub_request *subreq) { int large_lsn; int64_t nearest_event_time; struct request *ssd_request; + nearest_event_time = find_nearest_event(ssd); + + // only update ssd->current time if subreq is null + // this is used only after the "tracefile" is eof + // until the request queue in this ssd is empty + if (subreq == NULL) { + ssd->current_time = nearest_event_time; + return SUCCESS; + } + large_lsn = (int)((ssd->parameter->subpage_page*ssd->parameter->page_block*ssd->parameter->block_plane*ssd->parameter->plane_die*ssd->parameter->die_chip*ssd->parameter->chip_num)*(1-ssd->parameter->overprovide)); subreq->lsn = subreq->lsn % large_lsn; - nearest_event_time = find_nearest_event(ssd); if (nearest_event_time == MAX_INT64) { ssd->current_time = subreq->begin_time; } else { @@ -366,7 +570,6 @@ int raid_ssd_interface(struct ssd_info* ssd, struct raid_sub_request *subreq) { } } - ssd_request = (struct request*) malloc(sizeof(struct request)); alloc_assert(ssd_request, "ssd_request"); memset(ssd_request, 0, sizeof(struct request)); @@ -418,6 +621,7 @@ void raid_ssd_trace_output(struct ssd_info* ssd) { latency = 0; if (req->response_time != 0) { latency = req->response_time - req->time; + printf("%16lld %10d %6d %2d %16lld %16lld %10lld %2d %10lld\n",req->time,req->lsn, req->size, req->operation, req->begin_time, req->response_time, latency, req->meet_gc_flag, req->meet_gc_remaining_time); fprintf(ssd->outputfile,"%16lld %10d %6d %2d %16lld %16lld %10lld %2d %10lld\n",req->time,req->lsn, req->size, req->operation, req->begin_time, req->response_time, latency, req->meet_gc_flag, req->meet_gc_remaining_time); fflush(ssd->outputfile); fprintf(ssd->outfile_io,"%16lld %10d %6d %2d %16lld %16lld %10lld %2d %10lld\n",req->time,req->lsn, req->size, req->operation, req->begin_time, req->response_time, latency, req->meet_gc_flag, req->meet_gc_remaining_time); fflush(ssd->outfile_io); if (req->operation == WRITE) { @@ -463,6 +667,7 @@ void raid_ssd_trace_output(struct ssd_info* ssd) { if (is_all_sub_completed) { latency = end_time-req->time; + printf("%16lld %10d %6d %2d %16lld %16lld %10lld %2d %10lld\n",req->time,req->lsn, req->size, req->operation, req->begin_time, req->response_time, latency, req->meet_gc_flag, req->meet_gc_remaining_time); fprintf(ssd->outputfile,"%16lld %10d %6d %2d %16lld %16lld %10lld %2d %10lld\n",req->time,req->lsn, req->size, req->operation, req->begin_time, req->response_time, latency, req->meet_gc_flag, req->meet_gc_remaining_time); fflush(ssd->outputfile); fprintf(ssd->outfile_io,"%16lld %10d %6d %2d %16lld %16lld %10lld %2d %10lld\n",req->time,req->lsn, req->size, req->operation, req->begin_time, req->response_time, latency, req->meet_gc_flag, req->meet_gc_remaining_time); @@ -511,7 +716,6 @@ void raid_ssd_trace_output(struct ssd_info* ssd) { } } - return; } @@ -551,6 +755,27 @@ void ssd_delete_request_from_queue(struct ssd_info* ssd, struct request *req) { return; } +void raid_print_req_queue(struct raid_info* raid) { + struct raid_request* rreq; + struct raid_sub_request *srreq; + int rreq_id = 0; + + printf(" ============ RAID REQUEST QUEUE ============ \n"); + rreq = raid->request_queue; + while (rreq != NULL) { + printf(" [%d] %lld %lld %u %u %u\n", rreq_id, rreq->begin_time, rreq->response_time, rreq->lsn, rreq->size, rreq->operation); + srreq = rreq->subs; + while (srreq != NULL) { + printf(" %u %u %lld %lld\n", srreq->disk_id, srreq->current_state, srreq->begin_time, srreq->complete_time); + srreq = srreq->next_node; + } + rreq = rreq->next_node; + rreq_id++; + } + printf(" ============ RAID REQUEST QUEUE ============ \n"); + +} + struct raid_info* simulate_raid5(struct raid_info* raid) { printf("Work in progress for simualting raid 5 ...\n"); diff --git a/raid.h b/raid.h index 37f414d..3e003d1 100644 --- a/raid.h +++ b/raid.h @@ -1,4 +1,4 @@ -#define RAID_REQUEST_QUEUE_CAPACITY 10 +#define RAID_REQUEST_QUEUE_CAPACITY 20 #define RAID_STRIPE_SIZE_BYTE 65536 #define RAID_BLOCK_SIZE_BYTE 512 #define RAID_TO_SSD_LATENCY_NS 500000000 @@ -28,14 +28,16 @@ struct raid_info* simulate_raid0(struct raid_info*); struct raid_info* simulate_raid5(struct raid_info*); int raid_simulate_ssd(struct raid_info*, int); int raid_ssd_interface(struct ssd_info*, struct raid_sub_request*); +int raid_ssd_get_requests(int disk_id, struct ssd_info *ssd, struct raid_info *raid); void raid_ssd_trace_output(struct ssd_info*); int raid_distribute_request(struct raid_info*, int64_t, unsigned int, unsigned int, unsigned int); int raid_clear_completed_request(struct raid_info*); void ssd_delete_request_from_queue(struct ssd_info*, struct request*); +void raid_print_req_queue(struct raid_info*); - +void break_raid0_tracefile(struct raid_info*); // reference: https://www.snia.org/sites/default/files/SNIA_DDF_Technical_Position_v2.0.pdf // block and sector is interchangable here diff --git a/ssd.c b/ssd.c index ad624e7..210f299 100644 --- a/ssd.c +++ b/ssd.c @@ -799,6 +799,7 @@ void trace_output(struct ssd_info* ssd){ if (flag == 1) { + req->response_time = end_time; latency = end_time-req->time; fprintf(ssd->outputfile,"%16lld %10d %6d %2d %16lld %16lld %10lld %2d %10lld\n",req->time,req->lsn, req->size, req->operation, req->begin_time, req->response_time, latency, req->meet_gc_flag, req->meet_gc_remaining_time); fflush(ssd->outputfile); From 17b50ced31774165715c2146715a6e740236f0a3 Mon Sep 17 00:00:00 2001 From: Fadhil Imam Kurnia Date: Mon, 25 Mar 2019 17:44:55 +0700 Subject: [PATCH 5/9] Add object file in gitignore --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 3552776..ce75bd5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,9 @@ .vscode ssd *.0 +*.o *~ *.trace .DS_Store .idea -cmake-build-debug \ No newline at end of file +cmake-build-debug From a4fea817d39f7f41b190203127640cafa4546baa Mon Sep 17 00:00:00 2001 From: Fadhil Imam Kurnia Date: Thu, 28 Mar 2019 21:45:57 +0700 Subject: [PATCH 6/9] update again --- raid.c | 59 +++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 38 insertions(+), 21 deletions(-) diff --git a/raid.c b/raid.c index 1a2e9c9..21646cb 100644 --- a/raid.c +++ b/raid.c @@ -32,6 +32,7 @@ struct raid_info* initialize_raid(struct raid_info* raid, struct user_args* uarg printf("Initializing disk%d\n", i); raid->connected_ssd[i] = initialize_ssd(raid->connected_ssd[i], uargs); + raid->connected_ssd[i]->diskid = i; raid->connected_ssd[i] = initiation(raid->connected_ssd[i]); raid->connected_ssd[i] = make_aged(raid->connected_ssd[i]); raid->connected_ssd[i] = pre_process_page(raid->connected_ssd[i]); @@ -191,6 +192,7 @@ struct raid_info* simulate_raid0(struct raid_info* raid) { char buffer[200]; long filepoint; + // Run the RAID0 simulation untill all the request is tracefile is processed while (flag != RAID_SIMULATION_FINISH) { // Stop the simulation, if we reach the end of the tracefile and request queue is empty @@ -198,6 +200,7 @@ struct raid_info* simulate_raid0(struct raid_info* raid) { flag = RAID_SIMULATION_FINISH; } + // Trying to get a request from tracefile if (!feof(raid->tracefile)) { // Read a request from tracefile @@ -217,11 +220,7 @@ struct raid_info* simulate_raid0(struct raid_info* raid) { } req_lsn = req_lsn%raid->max_lsn; - // if nearest event time is less than incoming time, than skip to insert this request - // if queue is full, skip this request too - // Set raid current_time - - // Check whether we can process this request or not, also set raid->current_time + // Check whether we can process this request or not nearest_event_time = raid_find_nearest_event(raid); printf(" nearest time %lld %lld %lld %d\n", nearest_event_time, req_incoming_time, raid->current_time, raid->request_queue_length); if (raid->request_queue_length >= RAID_REQUEST_QUEUE_CAPACITY) { @@ -255,20 +254,29 @@ struct raid_info* simulate_raid0(struct raid_info* raid) { // Interface layer interface_flag = raid_ssd_get_requests(i, ssd, raid); + printf(" Finish interface layer %d\n", interface_flag); // Buffer layer - if(interface_flag == 1) { + printf(" Entering buffer layer\n"); + if(interface_flag == 1) { + printf("buflyr: disk-%d %lld %u %u %u\n", i, ssd->request_tail->begin_time, ssd->request_tail->lsn, ssd->request_tail->size, ssd->request_tail->operation); if (ssd->parameter->dram_capacity!=0) { - buffer_management(ssd); + printf(" Buffer management %d\n", ssd->request_tail->operation); + buffer_management(ssd); + printf(" Distribute\n"); distribute(ssd); - } else { + } else { no_buffer_distribute(ssd); } } + printf(" Finish buffer layer\n"); // FTL+FCL+Flash layer + printf(" Entering process\n"); process(ssd); + printf(" Finish process\n"); raid_ssd_trace_output(ssd); + printf(" Finish trace output\n"); printf("end simulating disk %d\n", i); } @@ -282,10 +290,10 @@ struct raid_info* simulate_raid0(struct raid_info* raid) { } // raid_distribute_request will distribute single IO request in raid level -// to IO request in disk level. A single IO request can be multiple IO request +// to IO request in disk level. A single IO request can be splitted into multiple IO request // in disk level. This function return R_DIST_SUCCESS (0) if success and R_DIST_ERR (1) if not. int raid_distribute_request(struct raid_info* raid, int64_t req_incoming_time, unsigned int req_lsn, unsigned int req_size, unsigned int req_operation) { - unsigned int disk_id, strip_id, stripe_id, stripe_offset, strip_offset, disk_req_lsn, disk_req_size; + unsigned int disk_id, strip_id, stripe_id, stripe_offset, strip_offset, disk_req_lsn, disk_req_size, strip_offset_block; int req_size_block = req_size; struct raid_request* raid_req; struct raid_sub_request* raid_subreq; @@ -303,12 +311,13 @@ int raid_distribute_request(struct raid_info* raid, int64_t req_incoming_time, u while(req_size_block > 0){ stripe_id = req_lsn / raid->stripe_size_block; - stripe_offset = req_lsn - (stripe_id * raid->stripe_size_block); + stripe_offset = req_lsn - (stripe_id * raid->stripe_size_block); // in byte strip_id = stripe_offset / raid->strip_size_block; - strip_offset = stripe_offset % raid->strip_size_block; + strip_offset = stripe_offset % raid->strip_size_block; // in byte + strip_offset_block = strip_offset/raid->block_size; disk_id = strip_id; disk_req_lsn = (stripe_id * raid->strip_size_block) + strip_offset; - disk_req_size = (raid->strip_size_block - strip_offset >= req_size) ? raid->strip_size_block - strip_offset : req_size; + disk_req_size = (raid->strip_size_block - strip_offset_block >= req_size) ? raid->strip_size_block - strip_offset_block : req_size; // add sub_request to request printf("--> req distributed to ssd: %u %u %u %u %u\n", disk_id, stripe_id, strip_id, strip_offset, disk_req_lsn); @@ -346,17 +355,14 @@ int raid_clear_completed_request(struct raid_info* raid) { req_pointer = raid->request_queue; while (req_pointer != NULL){ - printf(" [x] %lld\n", req_pointer->begin_time); is_all_completed = is_need_move_forward = 1; subreq_pointer = req_pointer->subs; while (subreq_pointer != NULL){ - printf(" [-] %d %d %lld\n", subreq_pointer->disk_id, subreq_pointer->current_state, subreq_pointer->begin_time); if (subreq_pointer->current_state != R_SR_COMPLETE) is_all_completed = 0; subreq_pointer = subreq_pointer->next_node; } if (is_all_completed) { - printf(">>>>>> deleting req : %lld [%d]\n", req_pointer->begin_time, raid->request_queue_length); subreq_pointer = req_pointer->subs; while (subreq_pointer != NULL){ temp_sr = subreq_pointer; @@ -420,7 +426,6 @@ int raid_simulate_ssd(struct raid_info* raid, int disk_id) { } if (err != ERROR) { - printf(">>>>> Req inserted to ssd queue %lld!\n", ssd->request_tail->begin_time); if (ssd->parameter->dram_capacity!=0) { buffer_management(ssd);; distribute(ssd); @@ -435,6 +440,10 @@ int raid_simulate_ssd(struct raid_info* raid, int disk_id) { return 0; } +// raid_ssd_get_requests will try to insert request from raid request queue to +// ssd request queue. Return 1: request added to ssd request queue +// -1: no request added to ssd request queue +// 0: no request in raid req queue for this disk int raid_ssd_get_requests(int disk_id, struct ssd_info *ssd, struct raid_info *raid) { struct raid_request *rreq; struct raid_sub_request *rsreq; @@ -448,7 +457,7 @@ int raid_ssd_get_requests(int disk_id, struct ssd_info *ssd, struct raid_info *r rreq = raid->request_queue; - // get request for this disk from raid req queue + // get first unprocessed request for this disk from raid req queue while (rreq != NULL && !is_found) { rsreq = rreq->subs; while (rsreq != NULL) { @@ -461,10 +470,16 @@ int raid_ssd_get_requests(int disk_id, struct ssd_info *ssd, struct raid_info *r rreq = rreq->next_node; } + nearest_event_time=find_nearest_event(ssd); + // no request for this disk - if (rsreq == NULL) return 0; + if (rsreq == NULL || !is_found) { + if (nearest_event_time != MAX_INT64) + ssd->current_time=nearest_event_time; + return 0; + } - // insert this request to requst queue in ssd + // insert this request to ssd's request queue req_device = disk_id; req_time = rsreq->begin_time; req_lsn = rsreq->lsn; @@ -478,7 +493,6 @@ int raid_ssd_get_requests(int disk_id, struct ssd_info *ssd, struct raid_info *r large_lsn=(int)((ssd->parameter->subpage_page*ssd->parameter->page_block*ssd->parameter->block_plane*ssd->parameter->plane_die*ssd->parameter->die_chip*ssd->parameter->chip_num)*(1-ssd->parameter->overprovide)); req_lsn = req_lsn%large_lsn; - nearest_event_time=find_nearest_event(ssd); if (nearest_event_time==MAX_INT64) { ssd->current_time = req_time; @@ -501,6 +515,9 @@ int raid_ssd_get_requests(int disk_id, struct ssd_info *ssd, struct raid_info *r exit(100); } + // set this raid's sub request state to R_SR_PROCESS + rsreq->current_state = R_SR_PROCESS; + ssd_request = (struct request*) malloc(sizeof(struct request)); alloc_assert(ssd_request, "ssd_request"); memset(ssd_request, 0, sizeof(struct request)); From 438d10f853b26091336281680931e3d4dc4900fc Mon Sep 17 00:00:00 2001 From: Fadhil Imam Kurnia Date: Tue, 2 Apr 2019 00:31:32 +0700 Subject: [PATCH 7/9] finish initial code for simulate raid0 --- flash.c | 3 +- processing/cdf | 0 processing/cdf_raid | 2 +- raid.c | 86 ++++++++++++++++++++++++++------------------- ssd.c | 3 -- 5 files changed, 52 insertions(+), 42 deletions(-) mode change 100644 => 100755 processing/cdf mode change 100644 => 100755 processing/cdf_raid diff --git a/flash.c b/flash.c index 56efa5c..d4c7bec 100644 --- a/flash.c +++ b/flash.c @@ -775,7 +775,8 @@ struct sub_request * find_read_sub_request(struct ssd_info * ssd, unsigned int c } else { - printf("Error! Can't find the sub request. [%lld %u]\n", sub->begin_time, sub->operation); + printf("Error! Can't find the sub request. {begin_time=%lld ope=%u}\n", sub->begin_time, sub->operation); + getchar(); } } } diff --git a/processing/cdf b/processing/cdf old mode 100644 new mode 100755 diff --git a/processing/cdf_raid b/processing/cdf_raid old mode 100644 new mode 100755 index 653411f..83f1913 --- a/processing/cdf_raid +++ b/processing/cdf_raid @@ -185,4 +185,4 @@ def plot_graph(main_graph, disk_graph, iolog_file, ndisk, nogc = False): return if __name__ == "__main__": - main(sys.argv[1:]) \ No newline at end of file + main(sys.argv[1:]) diff --git a/raid.c b/raid.c index 21646cb..967cdb1 100644 --- a/raid.c +++ b/raid.c @@ -71,6 +71,8 @@ struct raid_request* initialize_raid_request(struct raid_request* raid_req, int6 } struct raid_sub_request* initialize_raid_sub_request(struct raid_sub_request* raid_subreq, struct raid_request* raid_req, unsigned int disk_id, unsigned int stripe_id, unsigned int strip_id, unsigned int strip_offset, unsigned int lsn, unsigned int size, unsigned int operation) { + struct raid_sub_request *ptr = NULL; + raid_subreq->disk_id = disk_id; raid_subreq->stripe_id = stripe_id; raid_subreq->strip_id = strip_id; @@ -84,8 +86,11 @@ struct raid_sub_request* initialize_raid_sub_request(struct raid_sub_request* ra if (raid_req->subs == NULL) { raid_req->subs = raid_subreq; } else { - raid_req->subs->next_node = raid_subreq; - raid_req->subs = raid_subreq; + ptr = raid_req->subs; + while(ptr->next_node != NULL) { + ptr = ptr->next_node; + } + ptr->next_node = raid_subreq; } return raid_subreq; } @@ -114,8 +119,13 @@ int simulate_raid(struct user_args* uargs) { } void free_raid_ssd_and_tracefile(struct raid_info* raid) { + struct ssd_info *ssd; + for (int i = 0; i < raid->num_disk; i++) { - free(raid->connected_ssd[i]); + ssd = raid->connected_ssd[i]; + statistic_output(ssd); + close_file(ssd); + free(ssd); } fclose(raid->tracefile); } @@ -225,9 +235,9 @@ struct raid_info* simulate_raid0(struct raid_info* raid) { printf(" nearest time %lld %lld %lld %d\n", nearest_event_time, req_incoming_time, raid->current_time, raid->request_queue_length); if (raid->request_queue_length >= RAID_REQUEST_QUEUE_CAPACITY) { fseek(raid->tracefile,filepoint,0); - raid->current_time = nearest_event_time; is_accept_req = 0; } + if (nearest_event_time != MAX_INT64) raid->current_time = nearest_event_time; if (is_accept_req) { printf("req inserted: %lld %d %d %d %d [%d]\n", req_incoming_time, req_device_id, req_lsn, req_size, req_operation, raid->request_queue_length); @@ -247,38 +257,27 @@ struct raid_info* simulate_raid0(struct raid_info* raid) { // simulate all the ssd in the raid, // this is corresponding to simulate(ssd_info *ssd) function in ssd.c for(int i = 0; i < raid->num_disk; i++) { - printf("begin simulating disk %d\n", i); // raid_simulate_ssd(raid, i); ssd = raid->connected_ssd[i]; // Interface layer interface_flag = raid_ssd_get_requests(i, ssd, raid); - printf(" Finish interface layer %d\n", interface_flag); // Buffer layer - printf(" Entering buffer layer\n"); if(interface_flag == 1) { - printf("buflyr: disk-%d %lld %u %u %u\n", i, ssd->request_tail->begin_time, ssd->request_tail->lsn, ssd->request_tail->size, ssd->request_tail->operation); if (ssd->parameter->dram_capacity!=0) { - printf(" Buffer management %d\n", ssd->request_tail->operation); buffer_management(ssd); - printf(" Distribute\n"); distribute(ssd); } else { no_buffer_distribute(ssd); } } - printf(" Finish buffer layer\n"); // FTL+FCL+Flash layer - printf(" Entering process\n"); process(ssd); - printf(" Finish process\n"); raid_ssd_trace_output(ssd); - printf(" Finish trace output\n"); - - printf("end simulating disk %d\n", i); + } // remove processed request from raid queue @@ -342,7 +341,7 @@ int raid_distribute_request(struct raid_info* raid, int64_t req_incoming_time, u raid->request_tail->next_node = raid_req; raid->request_tail = raid_req; } - raid->request_queue_length++; + raid->request_queue_length = raid->request_queue_length + 1; } return R_DIST_SUCCESS; @@ -369,16 +368,17 @@ int raid_clear_completed_request(struct raid_info* raid) { subreq_pointer = temp_sr->next_node; free(temp_sr); } + req_pointer->subs = NULL; if (raid->request_queue_length == 1) { // the only element in queue - free(req_pointer); + free((void *)req_pointer); req_pointer = NULL; raid->request_queue = raid->request_tail = NULL; is_need_move_forward = 0; } else if (raid->request_queue == req_pointer) { // first element in queue with multiple elements raid->request_queue = req_pointer->next_node; raid->request_queue->prev_node = NULL; - free(req_pointer); + free((void *)req_pointer); req_pointer = raid->request_queue; is_need_move_forward = 0; } else { // middle or last element in queue @@ -389,11 +389,11 @@ int raid_clear_completed_request(struct raid_info* raid) { } else { (req_pointer->next_node)->prev_node = temp_r; } - free(req_pointer); + free((void *)req_pointer); req_pointer = temp_r; } - raid->request_queue_length -= 1; + raid->request_queue_length = raid->request_queue_length - 1; } if (req_pointer != NULL && is_need_move_forward) @@ -486,7 +486,7 @@ int raid_ssd_get_requests(int disk_id, struct ssd_info *ssd, struct raid_info *r req_size = rsreq->size; req_ope = rsreq->operation; - if (req_device < 0 || req_size < 0 || req_lsn < 0 || req_ope < 0) { + if (req_device < 0 || req_size < 0 || req_lsn < 0 || !(req_ope == WRITE || req_ope == READ)) { printf("Error! wrong io request from raid controller\n"); exit(100); } @@ -637,7 +637,7 @@ void raid_ssd_trace_output(struct ssd_info* ssd) { while (req != NULL){ latency = 0; if (req->response_time != 0) { - latency = req->response_time - req->time; + latency = req->response_time-req->time; printf("%16lld %10d %6d %2d %16lld %16lld %10lld %2d %10lld\n",req->time,req->lsn, req->size, req->operation, req->begin_time, req->response_time, latency, req->meet_gc_flag, req->meet_gc_remaining_time); fprintf(ssd->outputfile,"%16lld %10d %6d %2d %16lld %16lld %10lld %2d %10lld\n",req->time,req->lsn, req->size, req->operation, req->begin_time, req->response_time, latency, req->meet_gc_flag, req->meet_gc_remaining_time); fflush(ssd->outputfile); fprintf(ssd->outfile_io,"%16lld %10d %6d %2d %16lld %16lld %10lld %2d %10lld\n",req->time,req->lsn, req->size, req->operation, req->begin_time, req->response_time, latency, req->meet_gc_flag, req->meet_gc_remaining_time); fflush(ssd->outfile_io); @@ -674,7 +674,7 @@ void raid_ssd_trace_output(struct ssd_info* ssd) { if (end_time < sub->complete_time) end_time = sub->complete_time; if((sub->current_state == SR_COMPLETE)||((sub->next_state==SR_COMPLETE)&&(sub->next_state_predict_time<=ssd->current_time))) { - sub = sub->next_node; + sub = sub->next_subs; } else { is_all_sub_completed = 0; break; @@ -719,7 +719,7 @@ void raid_ssd_trace_output(struct ssd_info* ssd) { } free(tmp->location); tmp->location=NULL; - free(tmp); + free((void *)tmp); tmp=NULL; } @@ -740,34 +740,46 @@ void raid_ssd_trace_output(struct ssd_info* ssd) { void ssd_delete_request_from_queue(struct ssd_info* ssd, struct request *req) { struct request *temp, *prev; + // update raid subrequest + (req->subreq_on_raid)->current_state = R_SR_COMPLETE; + (req->subreq_on_raid)->complete_time = req->response_time; + + // req is first element of queue if (req == ssd->request_queue) { - (req->subreq_on_raid)->current_state = R_SR_COMPLETE; - (req->subreq_on_raid)->complete_time = req->response_time; req->subreq_on_raid = NULL; ssd->request_queue = req->next_node; - if (req->need_distr_flag != NULL) free(req->need_distr_flag); - free(req); + free(req->need_distr_flag); + req->need_distr_flag=NULL; - ssd->request_queue=NULL; - ssd->request_tail=NULL; + // req is alone in the queue + if (ssd->request_tail == req) { + ssd->request_tail=NULL; + } + + free((void *)req); ssd->request_queue_length--; return; } + // find the prev req before req temp = ssd->request_queue; while (temp != NULL && temp != req) { prev = temp; temp = temp->next_node; } - if (temp == NULL) return; + if (temp == NULL || prev == NULL) { + printf("Error! can't find request that need to be deleted\n"); + exit(100); + } - prev->next_node = temp->next_node; - (req->subreq_on_raid)->current_state = R_SR_COMPLETE; - (req->subreq_on_raid)->complete_time = req->response_time; - if (req->need_distr_flag != NULL) free(req->need_distr_flag); - free(req); + prev->next_node = req->next_node; + if (ssd->request_tail == req) ssd->request_tail = prev; + req->next_node = NULL; + free(req->need_distr_flag); + req->need_distr_flag = NULL; + free((void *)req); ssd->request_queue_length--; return; } diff --git a/ssd.c b/ssd.c index df486f7..140b5f7 100644 --- a/ssd.c +++ b/ssd.c @@ -1023,8 +1023,6 @@ void statistic_output(struct ssd_info *ssd) fprintf(ssd->outputfile,"erase: %13u\n",erase); fflush(ssd->outputfile); - fclose(ssd->outputfile); - fprintf(ssd->statisticfile,"\n"); fprintf(ssd->statisticfile,"\n"); @@ -1066,7 +1064,6 @@ void statistic_output(struct ssd_info *ssd) fprintf(ssd->statisticfile,"erase: %13u\n",erase); fflush(ssd->statisticfile); - fclose(ssd->statisticfile); } From e77c3b17963d1769c5b36410ae50ca79125babcf Mon Sep 17 00:00:00 2001 From: Fadhil Imam Kurnia Date: Tue, 2 Apr 2019 01:50:51 +0700 Subject: [PATCH 8/9] Add raid logfile, bugfix close_file(ssd) --- pagemap.c | 2 +- raid.c | 97 +++++++++++++++++++++++++++++-------------------------- raid.h | 4 ++- ssd.c | 2 +- 4 files changed, 56 insertions(+), 49 deletions(-) diff --git a/pagemap.c b/pagemap.c index 05fb2ad..8a22a18 100644 --- a/pagemap.c +++ b/pagemap.c @@ -1251,7 +1251,7 @@ int delete_gc_node(struct ssd_info *ssd, unsigned int channel,struct gc_operatio double free_page_percent = gc_node->x_free_percentage; if (end_time != start_time) { - printf("%d \t %d \t %d \t %d \t%6.2f %8u %16lld %16lld %16lld\n", channel, gc_node->chip, gc_node->die, gc_node->plane, free_page_percent, moved_page, start_time, end_time, end_time-start_time); + printf("gc-disk-%d: %d \t %d \t %d \t %d \t%6.2f %8u %16lld %16lld %16lld\n", ssd->diskid, channel, gc_node->chip, gc_node->die, gc_node->plane, free_page_percent, moved_page, start_time, end_time, end_time-start_time); fprintf(ssd->outfile_gc, "%d \t %d \t %d \t %d \t%6.2f %8u %16lld %16lld %16lld\n", channel, gc_node->chip, gc_node->die, gc_node->plane, free_page_percent, moved_page, start_time, end_time, end_time-start_time); fflush(ssd->outfile_gc); ssd->num_gc++; diff --git a/raid.c b/raid.c index 967cdb1..b8a98d3 100644 --- a/raid.c +++ b/raid.c @@ -8,9 +8,13 @@ struct raid_info* initialize_raid(struct raid_info* raid, struct user_args* uargs) { struct ssd_info *ssd_pointer; unsigned int max_lsn_per_disk; + char *current_time; + char logfilename[80]; raid->raid_type = uargs->raid_type; raid->num_disk = uargs->num_disk; + + // try to access tracefile strcpy(raid->tracefilename, uargs->trace_filename); raid->tracefile = fopen(raid->tracefilename, "r"); if(raid->tracefile == NULL) { @@ -18,6 +22,18 @@ struct raid_info* initialize_raid(struct raid_info* raid, struct user_args* uarg exit(1); } + // prepare raid logfile + current_time = (char*) malloc(sizeof(char)*16); + get_current_time(current_time); + strcpy(logfilename, "raw/raid_"); strcat(logfilename, current_time); strcat(logfilename, ".log"); + strcpy(raid->logfilename, logfilename); + raid->logfile = fopen(raid->logfilename, "w"); + if (raid->logfile == NULL) { + printf("Error: can't create logfile for this raid simulation\n"); + exit(1); + } + + // prepare ssds struct raid->connected_ssd=malloc(sizeof(struct ssd_info) * raid->num_disk); alloc_assert(raid->connected_ssd, "connected ssd"); for (int i = 0; i < raid->num_disk; i++) { @@ -29,13 +45,19 @@ struct raid_info* initialize_raid(struct raid_info* raid, struct user_args* uarg // initialize each ssd in raid for (int i = 0; i < raid->num_disk; i++) { - printf("Initializing disk%d\n", i); + printf("\nInitializing disk%d\n", i); + + get_current_time(current_time); + strcpy(uargs->simulation_timestamp, current_time); raid->connected_ssd[i] = initialize_ssd(raid->connected_ssd[i], uargs); raid->connected_ssd[i]->diskid = i; raid->connected_ssd[i] = initiation(raid->connected_ssd[i]); raid->connected_ssd[i] = make_aged(raid->connected_ssd[i]); raid->connected_ssd[i] = pre_process_page(raid->connected_ssd[i]); + raid->connected_ssd[i]->tracefile = NULL; + + fprintf(raid->logfile, "raw/%s/\n", current_time); } // set raid block size and stripe size @@ -55,6 +77,8 @@ struct raid_info* initialize_raid(struct raid_info* raid, struct user_args* uarg if (raid->raid_type == RAID_5) raid->max_lsn -= max_lsn_per_disk; + free(current_time); + fclose(raid->logfile); printf("RAID initialized!\n"); return raid; @@ -141,6 +165,7 @@ int64_t raid_find_nearest_event(struct raid_info* raid) { return nearest_time; } +// break_raid0_tracefile is unused function, ignore this function! void break_raid0_tracefile(struct raid_info* raid) { long filepoint; char buffer[200]; @@ -178,7 +203,9 @@ void break_raid0_tracefile(struct raid_info* raid) { disk_req_size = (raid->strip_size_block - strip_offset >= req_size) ? raid->strip_size_block - strip_offset : req_size; // add sub_request to request + #ifdef DEBUG printf(" ---> req distributed to ssd: %u %u %u %u %u\n", disk_id, stripe_id, strip_id, strip_offset, disk_req_lsn); + #endif fprintf(tracefile[disk_id], "%lld 0 %u %u %u\n", req_incoming_time, disk_req_lsn, disk_req_size, req_operation); req_size_block = req_size_block - (raid->strip_size_block - strip_offset); @@ -232,7 +259,9 @@ struct raid_info* simulate_raid0(struct raid_info* raid) { // Check whether we can process this request or not nearest_event_time = raid_find_nearest_event(raid); + #ifdef DEBUG printf(" nearest time %lld %lld %lld %d\n", nearest_event_time, req_incoming_time, raid->current_time, raid->request_queue_length); + #endif if (raid->request_queue_length >= RAID_REQUEST_QUEUE_CAPACITY) { fseek(raid->tracefile,filepoint,0); is_accept_req = 0; @@ -240,7 +269,9 @@ struct raid_info* simulate_raid0(struct raid_info* raid) { if (nearest_event_time != MAX_INT64) raid->current_time = nearest_event_time; if (is_accept_req) { + #ifdef DEBUG printf("req inserted: %lld %d %d %d %d [%d]\n", req_incoming_time, req_device_id, req_lsn, req_size, req_operation, raid->request_queue_length); + #endif // insert request to raid rquest queue // a single request can be forwarder to multiple disk @@ -257,27 +288,7 @@ struct raid_info* simulate_raid0(struct raid_info* raid) { // simulate all the ssd in the raid, // this is corresponding to simulate(ssd_info *ssd) function in ssd.c for(int i = 0; i < raid->num_disk; i++) { - // raid_simulate_ssd(raid, i); - - ssd = raid->connected_ssd[i]; - - // Interface layer - interface_flag = raid_ssd_get_requests(i, ssd, raid); - - // Buffer layer - if(interface_flag == 1) { - if (ssd->parameter->dram_capacity!=0) { - buffer_management(ssd); - distribute(ssd); - } else { - no_buffer_distribute(ssd); - } - } - - // FTL+FCL+Flash layer - process(ssd); - raid_ssd_trace_output(ssd); - + raid_simulate_ssd(raid, i); } // remove processed request from raid queue @@ -319,7 +330,9 @@ int raid_distribute_request(struct raid_info* raid, int64_t req_incoming_time, u disk_req_size = (raid->strip_size_block - strip_offset_block >= req_size) ? raid->strip_size_block - strip_offset_block : req_size; // add sub_request to request + #ifdef DEBUG printf("--> req distributed to ssd: %u %u %u %u %u\n", disk_id, stripe_id, strip_id, strip_offset, disk_req_lsn); + #endif raid_subreq = (struct raid_sub_request*)malloc(sizeof(struct raid_sub_request)); alloc_assert(raid_subreq, "raid_sub_request"); memset(raid_subreq,0,sizeof(struct raid_sub_request)); @@ -402,42 +415,30 @@ int raid_clear_completed_request(struct raid_info* raid) { return 0; } -int raid_simulate_ssd(struct raid_info* raid, int disk_id) { +void raid_simulate_ssd(struct raid_info* raid, int disk_id) { // iterate raid request queue, find first incoming request for this disk struct ssd_info* ssd; - struct raid_request* req_pointer; - struct raid_sub_request* subreq_pointer; - int flag = 0, err = ERROR, is_found=0; + int interface_flag = 0; ssd = raid->connected_ssd[disk_id]; - req_pointer = raid->request_queue; - while(req_pointer != NULL && !is_found){ - subreq_pointer = req_pointer->subs; - while(subreq_pointer != NULL && !is_found){ - if (subreq_pointer->disk_id == disk_id && subreq_pointer->current_state == R_SR_PENDING) { - is_found = 1; - // insert to ssd queue - err = raid_ssd_interface(ssd, subreq_pointer); - if (err != ERROR) subreq_pointer->current_state = R_SR_PROCESS; - } - subreq_pointer = subreq_pointer->next_node; - } - req_pointer = req_pointer->next_node; - } - - if (err != ERROR) { + + // Interface layer + interface_flag = raid_ssd_get_requests(disk_id, ssd, raid); + + // Buffer layer + if(interface_flag == 1) { if (ssd->parameter->dram_capacity!=0) { - buffer_management(ssd);; - distribute(ssd); - } else { + buffer_management(ssd); + distribute(ssd); + } else { no_buffer_distribute(ssd); } } + // FTL+FCL+Flash layer process(ssd); raid_ssd_trace_output(ssd); - return 0; } // raid_ssd_get_requests will try to insert request from raid request queue to @@ -638,7 +639,9 @@ void raid_ssd_trace_output(struct ssd_info* ssd) { latency = 0; if (req->response_time != 0) { latency = req->response_time-req->time; + #ifdef DEBUG printf("%16lld %10d %6d %2d %16lld %16lld %10lld %2d %10lld\n",req->time,req->lsn, req->size, req->operation, req->begin_time, req->response_time, latency, req->meet_gc_flag, req->meet_gc_remaining_time); + #endif fprintf(ssd->outputfile,"%16lld %10d %6d %2d %16lld %16lld %10lld %2d %10lld\n",req->time,req->lsn, req->size, req->operation, req->begin_time, req->response_time, latency, req->meet_gc_flag, req->meet_gc_remaining_time); fflush(ssd->outputfile); fprintf(ssd->outfile_io,"%16lld %10d %6d %2d %16lld %16lld %10lld %2d %10lld\n",req->time,req->lsn, req->size, req->operation, req->begin_time, req->response_time, latency, req->meet_gc_flag, req->meet_gc_remaining_time); fflush(ssd->outfile_io); if (req->operation == WRITE) { @@ -684,7 +687,9 @@ void raid_ssd_trace_output(struct ssd_info* ssd) { if (is_all_sub_completed) { latency = end_time-req->time; + #ifdef DEBUG printf("%16lld %10d %6d %2d %16lld %16lld %10lld %2d %10lld\n",req->time,req->lsn, req->size, req->operation, req->begin_time, req->response_time, latency, req->meet_gc_flag, req->meet_gc_remaining_time); + #endif fprintf(ssd->outputfile,"%16lld %10d %6d %2d %16lld %16lld %10lld %2d %10lld\n",req->time,req->lsn, req->size, req->operation, req->begin_time, req->response_time, latency, req->meet_gc_flag, req->meet_gc_remaining_time); fflush(ssd->outputfile); fprintf(ssd->outfile_io,"%16lld %10d %6d %2d %16lld %16lld %10lld %2d %10lld\n",req->time,req->lsn, req->size, req->operation, req->begin_time, req->response_time, latency, req->meet_gc_flag, req->meet_gc_remaining_time); diff --git a/raid.h b/raid.h index 3e003d1..a7b6c8d 100644 --- a/raid.h +++ b/raid.h @@ -26,7 +26,7 @@ int64_t raid_find_nearest_event(struct raid_info*); int simulate_raid(struct user_args *); struct raid_info* simulate_raid0(struct raid_info*); struct raid_info* simulate_raid5(struct raid_info*); -int raid_simulate_ssd(struct raid_info*, int); +void raid_simulate_ssd(struct raid_info*, int); int raid_ssd_interface(struct ssd_info*, struct raid_sub_request*); int raid_ssd_get_requests(int disk_id, struct ssd_info *ssd, struct raid_info *raid); void raid_ssd_trace_output(struct ssd_info*); @@ -50,7 +50,9 @@ struct raid_info { unsigned int strip_size_block; // strip size in block char tracefilename[80]; + char logfilename[80]; FILE * tracefile; + FILE * logfile; int64_t current_time; unsigned int max_lsn; diff --git a/ssd.c b/ssd.c index 140b5f7..b1ed079 100644 --- a/ssd.c +++ b/ssd.c @@ -1389,7 +1389,7 @@ void prep_output_for_simulation(struct ssd_info *ssd) void close_file(struct ssd_info *ssd) { - if (ssd->tracefile) fclose(ssd->tracefile); + if (ssd->tracefile!=NULL) fclose(ssd->tracefile); if (ssd->outputfile) fclose(ssd->outputfile); if (ssd->statisticfile) fclose(ssd->statisticfile); if (ssd->statisticfile2) fclose(ssd->statisticfile2); From 6f7b0a587e1c210d47f4743bfeee6940e0195f36 Mon Sep 17 00:00:00 2001 From: Fadhil Imam Kurnia Date: Tue, 2 Apr 2019 01:51:48 +0700 Subject: [PATCH 9/9] remove unused function --- raid.c | 57 --------------------------------------------------------- raid.h | 2 -- 2 files changed, 59 deletions(-) diff --git a/raid.c b/raid.c index b8a98d3..1c717ce 100644 --- a/raid.c +++ b/raid.c @@ -165,63 +165,6 @@ int64_t raid_find_nearest_event(struct raid_info* raid) { return nearest_time; } -// break_raid0_tracefile is unused function, ignore this function! -void break_raid0_tracefile(struct raid_info* raid) { - long filepoint; - char buffer[200]; - int64_t req_incoming_time, nearest_event_time; - int req_device_id, req_lsn, req_size, req_operation, flag, err, is_accept_req; - unsigned int disk_id, strip_id, stripe_id, stripe_offset, strip_offset, disk_req_lsn, disk_req_size; - int req_size_block; - - FILE **tracefile; - tracefile = malloc(sizeof(FILE*) * raid->num_disk); - for(int i=0; i < raid->num_disk; i++) { - sprintf(buffer, "raid0disk%d.trace", i); - tracefile[i] = fopen(buffer, "w"); - if(tracefile[i] == NULL) { - printf("the %d tracefile can't be opened\n", i); - exit(1); - } - } - - while (!feof(raid->tracefile)) { - filepoint = ftell(raid->tracefile); - fgets (buffer, 200, raid->tracefile); - sscanf (buffer,"%lld %d %d %d %d", &req_incoming_time, &req_device_id, &req_lsn, &req_size, &req_operation); - - printf("%lld %d %d %d %d\n", req_incoming_time, req_device_id, req_lsn, req_size, req_operation); - req_size_block = req_size; - - while(req_size_block > 0){ - stripe_id = req_lsn / raid->stripe_size_block; - stripe_offset = req_lsn - (stripe_id * raid->stripe_size_block); - strip_id = stripe_offset / raid->strip_size_block; - strip_offset = stripe_offset % raid->strip_size_block; - disk_id = strip_id; - disk_req_lsn = (stripe_id * raid->strip_size_block) + strip_offset; - disk_req_size = (raid->strip_size_block - strip_offset >= req_size) ? raid->strip_size_block - strip_offset : req_size; - - // add sub_request to request - #ifdef DEBUG - printf(" ---> req distributed to ssd: %u %u %u %u %u\n", disk_id, stripe_id, strip_id, strip_offset, disk_req_lsn); - #endif - fprintf(tracefile[disk_id], "%lld 0 %u %u %u\n", req_incoming_time, disk_req_lsn, disk_req_size, req_operation); - - req_size_block = req_size_block - (raid->strip_size_block - strip_offset); - if (req_size_block > 0) { - req_size = req_size_block; - req_lsn = req_lsn + req_size; - } - } - - } - - for(int i=0; i < raid->num_disk; i++) { - fclose(tracefile[i]); - } -} - struct raid_info* simulate_raid0(struct raid_info* raid) { int req_device_id, req_lsn, req_size, req_operation, flag, err, is_accept_req, interface_flag; int64_t req_incoming_time, nearest_event_time; diff --git a/raid.h b/raid.h index a7b6c8d..3c82623 100644 --- a/raid.h +++ b/raid.h @@ -37,8 +37,6 @@ int raid_clear_completed_request(struct raid_info*); void ssd_delete_request_from_queue(struct ssd_info*, struct request*); void raid_print_req_queue(struct raid_info*); -void break_raid0_tracefile(struct raid_info*); - // reference: https://www.snia.org/sites/default/files/SNIA_DDF_Technical_Position_v2.0.pdf // block and sector is interchangable here struct raid_info {