void __rdev_perf_make_request(device_t *disk_device, header_t *req_header) { uint64_t now_ms = os_gettimeofday_msec(); uint64_t inter_arrival; int rw = -1; EXA_ASSERT(NBD_REQ_TYPE_IS_VALID(req_header->request_type)); switch (req_header->request_type) { case NBD_REQ_TYPE_READ: rw = __READ; break; case NBD_REQ_TYPE_WRITE: rw = __WRITE; break; case NBD_REQ_TYPE_LOCK: case NBD_REQ_TYPE_UNLOCK: EXA_ASSERT(false); /* FIXME: formerly this case was not handled */ } /* WARNING: be careful, although the first call is taken into account * here (for the inter-arrival time), the first exaperf log should not * be taken into consideration for the analysis. Max and mean value * are very big because of the history of the IOs. This happens even * if we start/stop the cluser between two experiments. */ if (disk_device->last_req_time[rw] != 0) { inter_arrival = now_ms - disk_device->last_req_time[rw]; exaperf_repart_add_value(disk_device->inter_arrival_repart[rw], inter_arrival); } disk_device->last_req_time[rw] = now_ms; req_header->rdev_submit_date = now_ms; }
void __serverd_perf_end_request(header_t *req_header) { double now = os_gettimeofday_msec(); int rw = -1; EXA_ASSERT(NBD_REQ_TYPE_IS_VALID(req_header->request_type)); switch (req_header->request_type) { case NBD_REQ_TYPE_READ: rw = __READ; break; case NBD_REQ_TYPE_WRITE: rw = __WRITE; break; case NBD_REQ_TYPE_LOCK: case NBD_REQ_TYPE_UNLOCK: EXA_ASSERT(false); /* FIXME: formerly this case was not handled */ } exaperf_duration_record(header_dur[rw], (double)now - req_header->header_submit_date); if (rw == __WRITE) exaperf_duration_record(data_dur, (double)now - req_header->data_submit_date); }
/** * The request is finished, ackwoledge upper layer. * This function reuse the request for the answer, thus req is modified. * * @param disk_device the device * @param header of the ended request */ static void handle_completed_io(device_t *disk_device, header_t *req) { EXA_ASSERT(NBD_REQ_TYPE_IS_VALID(req->io.desc.request_type)); if (req->io.desc.result != 0) exalog_trace("error %d: #%"PRIu64". %s (%d) %d sector at sector %"PRId64, req->io.desc.result, req->io.desc.req_num, (req->io.desc.request_type == NBD_REQ_TYPE_READ) ? "READ" : "WRITE", req->io.desc.request_type, req->io.desc.sector_nb, req->io.desc.sector); nbd_server_end_io(req); }
/** * send one request to device, it validate there is no problem with the * * @header IN request to do * OUT last request done * @return EXA_RDEV_REQUEST_END_OK new request submitted successfully and header * contains an old request succesfully done * EXA_RDEV_REQUEST_END_ERROR new request submitted successfully * and header contains an old request that fail * RDEV_REQUEST_NOT_ENOUGH_FREE_REQ not enough resources to submit a new request */ static int exa_td_process_one_request(header_t **header, device_t *disk_device) { void * buffer; int sector_nb; uint64_t sector; int retval; header_t *req_header = *header; /* FIXME this is a ugly hack to prevent compiler to complain about * uninitialized variable. Actually, this is because the request type * itself is f***ed up (no type and the funky use os bit masks...) * Please remove this whe reworking header_t content... */ rdev_op_t op = (rdev_op_t)-1; /* submit this new request to exa_rdev and so to the disk driver */ sector_nb = req_header->io.desc.sector_nb; buffer = req_header->io.buf; sector = req_header->io.desc.sector; EXA_ASSERT(NBD_REQ_TYPE_IS_VALID(req_header->io.desc.request_type)); switch (req_header->io.desc.request_type) { case NBD_REQ_TYPE_READ: EXA_ASSERT(!req_header->io.desc.flush_cache); op = RDEV_OP_READ; break; case NBD_REQ_TYPE_WRITE: if (req_header->io.desc.flush_cache) op = RDEV_OP_WRITE_BARRIER; else op = RDEV_OP_WRITE; break; } /* Be carefull the 'header' pointer can be modified */ retval = exa_rdev_make_request_new(op, (void *)header, sector + RDEV_RESERVED_AREA_IN_SECTORS, sector_nb, buffer, disk_device->handle); if (retval == RDEV_REQUEST_NOT_ENOUGH_FREE_REQ) return RDEV_REQUEST_NOT_ENOUGH_FREE_REQ; if (*header != NULL) (*header)->io.desc.result = retval == RDEV_REQUEST_END_OK ? 0 : -EIO; if (retval < 0) return RDEV_REQUEST_END_ERROR; return retval; }
void __serverd_perf_make_request(header_t *req_header) { uint64_t now_ms; double inter_arrival; double dist; int rw = -1; EXA_ASSERT(NBD_REQ_TYPE_IS_VALID(req_header->request_type)); switch (req_header->request_type) { case NBD_REQ_TYPE_READ: rw = __READ; break; case NBD_REQ_TYPE_WRITE: rw = __WRITE; break; case NBD_REQ_TYPE_LOCK: case NBD_REQ_TYPE_UNLOCK: EXA_ASSERT(false); /* FIXME: formerly this case was not handled */ } now_ms = os_gettimeofday_msec(); /* FIXME how is it supposed to be of an other type here ? */ if (req_header->type == NBD_HEADER_RH) { uint64_t lba_in_kbytes = req_header->sector / 2; /* add the lba in MB in the repartition */ exaperf_repart_add_value(lba_repart[rw], lba_in_kbytes / 1024); req_header->header_submit_date = now_ms; inter_arrival = (double)now_ms - last_req_time[rw]; dist = (double)req_header->sector - next_sector[rw]; exaperf_repart_add_value(inter_arrival_repart[rw], inter_arrival); exaperf_repart_add_value(distance_repart[rw], dist); exaperf_repart_add_value(req_size_repart[rw], (req_header->sector_nb/2.)); next_sector[rw] = req_header->sector + req_header->sector_nb; last_req_time[rw] = now_ms; } }
void __rdev_perf_end_request(device_t *disk_device, header_t *req_header) { double duration; int rw = -1; EXA_ASSERT(NBD_REQ_TYPE_IS_VALID(req_header->request_type)); switch (req_header->request_type) { case NBD_REQ_TYPE_READ: rw = __READ; break; case NBD_REQ_TYPE_WRITE: rw = __WRITE; break; case NBD_REQ_TYPE_LOCK: case NBD_REQ_TYPE_UNLOCK: EXA_ASSERT(false); /* FIXME: formerly this case was not handled */ } duration = (double)os_gettimeofday_msec() - req_header->rdev_submit_date; exaperf_duration_record(disk_device->rdev_dur[rw], duration); }