Brian King <brk...@linux.vnet.ibm.com> writes: > Hi Gabriel, > > This doesn't apply cleanly. Can you rebase the patch? Also, a couple of > minor comments below. >
Thanks for your review. I have rebased to HEAD and applied the fixes you suggested. -- >8 -- From: Wen Xiong <wenxi...@linux.vnet.ibm.com> This patch added maximum queue depth in GUI when creating an array. Also fixed some issues in query-qdepth and set-qdepth. Changes since v3: - Add missing parameter to printf. - Fix indentation in break. Changes since v2: - Move qdepth helper functions to iprlib. - Use ipr_max_queue_depth when initializing vset. - Remove faulty snprintf. Changes since v1: - Rebase to 2.4.10. - Implement Brian suggestions on calculating max_qdepth. - Change how Max queue depth property is displayed when doing disk config. - Fix segfault in ipr_set_dev_attr when there is no alternate path. Signed-off-by: Wen Xiong <wenxi...@linux.vnet.ibm.com> Signed-off-by: Gabriel Krisman Bertazi <kris...@linux.vnet.ibm.com> [Rebase to 2.4.10 and review fixes] --- iprconfig.c | 51 +++++++++++++++++++++++++++++++++++---------------- iprlib.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- iprlib.h | 4 ++++ 3 files changed, 96 insertions(+), 19 deletions(-) diff --git a/iprconfig.c b/iprconfig.c index 4d36f72..297fc96 100644 --- a/iprconfig.c +++ b/iprconfig.c @@ -3641,7 +3641,7 @@ int configure_raid_parameters(i_container *i_con) int *userptr = NULL; int *retptr; int max_x,max_y,start_y,start_x; - int qdepth, new_qdepth; + int qdepth, new_qdepth, max_qdepth; int cache_prot; getmaxyx(stdscr,max_y,max_x); @@ -3664,6 +3664,7 @@ int configure_raid_parameters(i_container *i_con) } } + max_qdepth = ipr_max_queue_depth(ioa, selected_count, ssd_num); if (ioa->sis64) qdepth = selected_count * 16; else @@ -3782,7 +3783,7 @@ int configure_raid_parameters(i_container *i_con) mvaddstr(6, 1, _("c=Change Setting")); mvaddstr(8, 0, "Protection Level . . . . . . . . . . . . :"); mvaddstr(9, 0, "Stripe Size . . . . . . . . . . . . . . :"); - mvprintw(10, 0, "Queue Depth (default = %3d). . . . . . . :", qdepth); + mvprintw(10, 0, "Queue Depth (default = %3d)(max = %3d) . :", qdepth, max_qdepth); if (ioa->vset_write_cache) mvprintw(11, 0, "Array Write Cache Policy . . . . . . . . :"); mvaddstr(max_y - 4, 0, _("Press Enter to Continue")); @@ -3924,10 +3925,8 @@ int configure_raid_parameters(i_container *i_con) if (rc == CANCEL_FLAG) continue; - if (new_qdepth > 128) - qdepth = 128; - else - qdepth = new_qdepth; + qdepth = (new_qdepth < max_qdepth)? new_qdepth:max_qdepth; + continue; } else if (cur_field_index == 4 && ioa->vset_write_cache) { userptr = realloc(userptr, @@ -10868,8 +10867,6 @@ static int disk_config_menu(struct disk_config_attr *disk_config_attr, if (disk_config_attr->option == 1) { /* queue depth*/ rc = display_input(start_row, &disk_config_attr->queue_depth); - if (disk_config_attr->queue_depth > 128) - disk_config_attr->queue_depth = 128; } else if (disk_config_attr->option == 3) { /* tag command queue.*/ num_menu_items = 2; menu_item = malloc(sizeof(ITEM **) * (num_menu_items + 1)); @@ -10998,7 +10995,7 @@ int change_disk_config(i_container * i_con) struct ipr_dev *dev; char qdepth_str[4]; char format_timeout_str[8]; - char buffer[128]; + char buffer[200]; i_container *temp_i_con; int found = 0; char *input; @@ -11012,6 +11009,7 @@ int change_disk_config(i_container * i_con) int tcq_warning = 0; int tcq_blocked = 0; int tcq_enabled = 0; + int num_devs, ssd_num_devs, max_qdepth; rc = RC_SUCCESS; @@ -11073,10 +11071,18 @@ int change_disk_config(i_container * i_con) tcq_warning = tcq_blocked = 0; if (!tcq_blocked || ipr_is_gscsi(dev)) { - body = add_line_to_body(body,_("Queue Depth"), "%3"); + ipr_count_devices_in_vset(dev, &num_devs, &ssd_num_devs); + max_qdepth = ipr_max_queue_depth(dev->ioa, num_devs, ssd_num_devs); + sprintf(buffer, "Queue Depth (max = %03d)", max_qdepth); + body = add_line_to_body(body, buffer, "%3"); + disk_config_attr[0].option = 1; + + if (disk_attr.queue_depth > max_qdepth) + disk_attr.queue_depth = max_qdepth; + disk_config_attr[0].queue_depth = disk_attr.queue_depth; - sprintf(qdepth_str,"%d",disk_config_attr[0].queue_depth); + sprintf(qdepth_str, "%d", disk_config_attr[0].queue_depth); i_con = add_i_con(i_con, qdepth_str, &disk_config_attr[0]); } @@ -11140,7 +11146,10 @@ int change_disk_config(i_container * i_con) if (config_attr->option == 1) { sprintf(temp_i_con->field_data,"%d", config_attr->queue_depth); - disk_attr.queue_depth = config_attr->queue_depth; + if (config_attr->queue_depth > max_qdepth) + disk_attr.queue_depth = max_qdepth; + else + disk_attr.queue_depth = config_attr->queue_depth; } else if (config_attr->option == 2) { sprintf(temp_i_con->field_data,"%d hr", config_attr->format_timeout); @@ -14003,12 +14012,12 @@ static int format_for_raid(char **args, int num_args) **/ static int raid_create(char **args, int num_args) { - int i, num_devs = 0, rc, prot_level; + int i, num_devs = 0, ssd_num_devs = 0, rc, prot_level; int non_4k_count = 0, is_4k_count = 0; int next_raid_level, next_stripe_size, next_qdepth, next_label; char *raid_level = IPR_DEFAULT_RAID_LVL; char label[8]; - int stripe_size, qdepth, zeroed_devs, skip_format; + int stripe_size, qdepth, zeroed_devs, skip_format, max_qdepth; int next_vcache, vcache = -1; struct ipr_dev *dev; struct sysfs_dev *sdev; @@ -14072,6 +14081,8 @@ static int raid_create(char **args, int num_args) strcpy(label, args[i]); } else if ((dev = find_dev(args[i]))) { + if (dev->block_dev_class & IPR_SSD) + ssd_num_devs++; num_devs++; if (zeroed_devs) ipr_add_zeroed_dev(dev); @@ -14139,6 +14150,9 @@ IOA write cache. Use --force to force creation.\n"); if (!stripe_size) stripe_size = ntohs(cap->recommended_stripe_size); + max_qdepth = ipr_max_queue_depth(dev->ioa, num_devs, ssd_num_devs); + if (qdepth > max_qdepth) + qdepth = max_qdepth; if (!qdepth) { if (ioa->sis64) qdepth = num_devs * 16; @@ -15376,6 +15390,7 @@ static int set_qdepth(char **args, int num_args) int rc; struct ipr_disk_attr attr; struct ipr_dev *dev = find_dev(args[0]); + int num_devs, ssd_num_devs, max_qdepth; if (!dev) { fprintf(stderr, "Cannot find %s\n", args[0]); @@ -15392,10 +15407,14 @@ static int set_qdepth(char **args, int num_args) if (rc) return rc; + ipr_count_devices_in_vset(dev, &num_devs, &ssd_num_devs); + max_qdepth = ipr_max_queue_depth(dev->ioa, num_devs, ssd_num_devs); + attr.queue_depth = strtoul(args[1], NULL, 10); - if (attr.queue_depth > 255) { - fprintf(stderr, "Invalid queue depth %s\n", args[1]); + if (attr.queue_depth > max_qdepth) { + fprintf(stderr, "Invalid queue depth, max queue depth is %d\n", + max_qdepth); return -EINVAL; } diff --git a/iprlib.c b/iprlib.c index bcd8862..1b8cc84 100644 --- a/iprlib.c +++ b/iprlib.c @@ -2101,6 +2101,7 @@ static int __tool_init(int save_state) DIR *dirfd, *host_dirfd; struct dirent *dent, *host_dent; ssize_t len; + char queue_str[256]; save_old_config(); @@ -2158,6 +2159,11 @@ static int __tool_init(int save_state) sscanf(fw_str, "%d", &fw_type); if (ipr_debug) syslog(LOG_INFO, "tool_init: fw_type attr = %d.\n", fw_type); + + len = sysfs_read_attr(scsipath, "can_queue", queue_str, 256); + if (len < 0) + ioa_dbg(ipr_ioa, "Failed to read can_queue attribute"); + sscanf(queue_str, "%d", &ipr_ioa->can_queue); break; } closedir(host_dirfd); @@ -6957,6 +6963,8 @@ static void ipr_save_dev_attr(struct ipr_dev *dev, char *field, char *value, int update) { char category[100]; + struct ipr_dev *alt_dev = dev->alt_path; + if (dev->scsi_dev_data->device_id) sprintf(category,"[%s %lx]", IPR_CATEGORY_DEVICE, dev->scsi_dev_data->device_id); @@ -6966,6 +6974,8 @@ static void ipr_save_dev_attr(struct ipr_dev *dev, char *field, dev->scsi_dev_data->lun); ipr_save_attr(dev->ioa, category, field, value, update); + if (alt_dev) + ipr_save_attr(alt_dev->ioa, category, field, value, update); } /** @@ -7518,6 +7528,11 @@ int ipr_set_dev_attr(struct ipr_dev *dev, struct ipr_disk_attr *attr, int save) } else { if (ipr_write_dev_attr(dev, "queue_depth", temp)) return -EIO; + + if (dev->alt_path && ipr_write_dev_attr(dev->alt_path, + "queue_depth", + temp)) + return -EIO; } if (save) ipr_save_dev_attr(dev, IPR_QUEUE_DEPTH, temp, 1); @@ -9357,6 +9372,44 @@ static int setup_page0x0a(struct ipr_dev *dev) return rc; } +void ipr_count_devices_in_vset(struct ipr_dev *dev, int *num_devs, + int *ssd_num_devs) +{ + struct ipr_dev *vset, *temp; + int devs_cnt = 0, ssd_devs_cnt = 0; + + if (ipr_is_volume_set(dev)) { + for_each_dev_in_vset(dev, temp) { + devs_cnt++; + if (temp->block_dev_class & IPR_SSD) + ssd_devs_cnt++; + fprintf(stdout, "%s\n", temp->gen_name); + } + } else { + devs_cnt++; + if (dev->block_dev_class & IPR_SSD) + ssd_devs_cnt++; + } + + *num_devs = devs_cnt; + *ssd_num_devs = ssd_devs_cnt; + +} + +int ipr_max_queue_depth(struct ipr_ioa *ioa, int num_devs, int num_ssd_devs) +{ + int max_qdepth; + + if (num_ssd_devs == num_devs) + max_qdepth = MIN(num_devs * 64, ioa->can_queue); + else if (num_ssd_devs) + max_qdepth = MIN(num_devs * 32, ioa->can_queue); + else + max_qdepth = MIN(num_devs * 16, ioa->can_queue); + + return MAX(max_qdepth, 128); +} + /** * init_vset_dev - * @dev: ipr dev struct @@ -9374,7 +9427,7 @@ static void init_vset_dev(struct ipr_dev *dev) struct ipr_query_res_state res_state; char q_depth[100]; char cur_depth[100], saved_depth[100]; - int depth, rc; + int depth, rc, num_devs, ssd_num_devs; char saved_cache[100]; memset(&res_state, 0, sizeof(res_state)); @@ -9383,9 +9436,10 @@ static void init_vset_dev(struct ipr_dev *dev) return; if (!ipr_query_resource_state(dev, &res_state)) { - depth = res_state.vset.num_devices_in_vset * 4; + ipr_count_devices_in_vset(dev, &num_devs, &ssd_num_devs); + depth = ipr_max_queue_depth(dev->ioa, num_devs, ssd_num_devs); + snprintf(q_depth, sizeof(q_depth), "%d", depth); - q_depth[sizeof(q_depth)-1] = '\0'; if (ipr_read_dev_attr(dev, "queue_depth", cur_depth, 100)) return; rc = ipr_get_saved_dev_attr(dev, IPR_QUEUE_DEPTH, saved_depth); diff --git a/iprlib.h b/iprlib.h index 81d8eef..b122fcc 100644 --- a/iprlib.h +++ b/iprlib.h @@ -51,6 +51,7 @@ #include <time.h> #include <limits.h> #include <zlib.h> +#include <sys/param.h> typedef uint8_t u8; typedef uint16_t u16; @@ -1542,6 +1543,7 @@ struct ipr_ioa { #define IPR_SIS32 0x00 #define IPR_SIS64 0x01 u8 support_4k:1; + int can_queue; enum ipr_tcq_mode tcq_mode; u16 pci_vendor; u16 pci_device; @@ -2911,6 +2913,8 @@ int ipr_improper_device_type(struct ipr_dev *); int ipr_get_fw_version(struct ipr_dev *, u8 release_level[4]); int ipr_get_live_dump(struct ipr_ioa *); int ipr_jbod_sysfs_bind(struct ipr_dev *, u8); +int ipr_max_queue_depth(struct ipr_ioa *ioa, int num_devs, int num_ssd_devs); +void ipr_count_devices_in_vset(struct ipr_dev *, int *num_devs, int *ssd_num_devs); static inline u32 ipr_get_dev_res_handle(struct ipr_ioa *ioa, struct ipr_dev_record *dev_rcd) { -- 2.1.0 ------------------------------------------------------------------------------ _______________________________________________ Iprdd-devel mailing list Iprdd-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/iprdd-devel