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 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 | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++----------- iprlib.c | 17 +++++++++++- iprlib.h | 2 ++ 3 files changed, 92 insertions(+), 17 deletions(-) diff --git a/iprconfig.c b/iprconfig.c index 3189af0..83c54e7 100644 --- a/iprconfig.c +++ b/iprconfig.c @@ -3642,7 +3642,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); @@ -3665,6 +3665,7 @@ int configure_raid_parameters(i_container *i_con) } } + max_qdepth = get_max_queue_depth(ioa, selected_count, ssd_num); if (ioa->sis64) qdepth = selected_count * 16; else @@ -3783,7 +3784,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); if (ioa->vset_write_cache) mvprintw(11, 0, "Array Write Cache Policy . . . . . . . . :"); mvaddstr(max_y - 4, 0, _("Press Enter to Continue")); @@ -3925,10 +3926,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, @@ -10834,6 +10833,43 @@ int disk_config(i_container * i_con) return rc; } +static void get_number_devices(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 get_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); +} + struct disk_config_attr { int option; int queue_depth; @@ -10869,8 +10905,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)); @@ -10999,7 +11033,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; @@ -11013,6 +11047,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; @@ -11074,10 +11109,20 @@ 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"); + get_number_devices(dev, &num_devs, &ssd_num_devs); + max_qdepth = get_max_queue_depth(dev->ioa, num_devs, ssd_num_devs); + sprintf(buffer, "%d", max_qdepth); + + 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]); } @@ -11141,7 +11186,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); @@ -13878,12 +13926,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; @@ -13947,6 +13995,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); @@ -14014,6 +14064,9 @@ IOA write cache. Use --force to force creation.\n"); if (!stripe_size) stripe_size = ntohs(cap->recommended_stripe_size); + max_qdepth = get_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; @@ -15241,6 +15294,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]); @@ -15257,10 +15311,14 @@ static int set_qdepth(char **args, int num_args) if (rc) return rc; + get_number_devices(dev, &num_devs, &ssd_num_devs); + max_qdepth = get_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 a899e1b..ac10fec 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,7 +2159,12 @@ 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); - break; + + 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); if (ipr_ioa->host_num < 0) { @@ -6943,6 +6949,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); @@ -6952,6 +6960,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); } /** @@ -7504,6 +7514,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); diff --git a/iprlib.h b/iprlib.h index 16fe1e1..8b90c40 100644 --- a/iprlib.h +++ b/iprlib.h @@ -49,6 +49,7 @@ #include <bits/sockaddr.h> #include <linux/netlink.h> #include <time.h> +#include <sys/param.h> typedef uint8_t u8; typedef uint16_t u16; @@ -1540,6 +1541,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; -- 2.1.0 ------------------------------------------------------------------------------ Site24x7 APM Insight: Get Deep Visibility into Application Performance APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month Monitor end-to-end web transactions and take corrective actions now Troubleshoot faster and improve end-user experience. Signup Now! http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140 _______________________________________________ Iprdd-devel mailing list Iprdd-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/iprdd-devel