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

Reply via email to