If there is no saved write cache policy for a JBOD, we would like the write cache policy to default to write back for the best performance. However, we currently have code in check_current_config that reads the current write cache policy and saves it in the ipr_dev struct. Then iprinit calls ipr_get_dev_attr which sets the write_cache_policy attribute in the local ipr_disk_attr structure, we call ipr_modify_dev_attr, which looks for a saved write cache policy and we don't find one, then we change the cache policy to write back. Then we call ipr_set_dev_attr, see that the now current write cache setting does not match what the attribute was after calling ipr_get_dev_attr earlier, and then ends up reverting the cache policy back to what it was originally, which is write through.
To fix this we do a few things: 1. Removing this write_cache_policy field in the ipr_dev struct. 2. Remove the special code in init_gpdd_dev to set the write cache policy and move it into ipr_set_dev_attr. 3. Enhance ipr_modify_dev_attr to set write_cache_policy to the default value of write back if there is no saved write cache policy. Signed-off-by: Brian King <brk...@linux.vnet.ibm.com> --- iprlib.c | 39 ++++++++++++++++++--------------------- iprlib.h | 1 - 2 files changed, 18 insertions(+), 22 deletions(-) diff -puN iprlib.h~iprutils_fix_wcache_policy iprlib.h --- iprutils.patches/iprlib.h~iprutils_fix_wcache_policy 2017-06-09 16:21:23.225725484 -0500 +++ iprutils.patches-bjking1/iprlib.h 2017-06-09 16:21:34.568667807 -0500 @@ -1483,7 +1483,6 @@ struct ipr_dev { u8 active_suspend; u32 is_suspend_cand:1; u32 is_resume_cand:1; - u8 write_cache_policy:1; u8 supports_4k:1; u8 supports_5xx:1; u8 read_c7:1; diff -puN iprlib.c~iprutils_fix_wcache_policy iprlib.c --- iprutils.patches/iprlib.c~iprutils_fix_wcache_policy 2017-06-09 16:21:38.594647336 -0500 +++ iprutils.patches-bjking1/iprlib.c 2017-06-09 20:20:17.013028680 -0500 @@ -3593,6 +3593,7 @@ static int ipr_set_dev_wcache_policy (co char *cache_type; char current_type[100]; + memset(current_type, 0, sizeof(current_type)); sprintf(path, "/sys/class/scsi_disk/%s", dev->scsi_dev_data->sysfs_device_name); @@ -6646,15 +6647,6 @@ void check_current_config(bool allow_reb strcpy(ioa->dev[device_count].gen_name, scsi_dev_data->gen_name); - if (scsi_dev_data->type == TYPE_DISK) { - if (ipr_dev_wcache_policy(&(ioa->dev[device_count])) == IPR_DEV_CACHE_WRITE_BACK) - ioa->dev[device_count].write_cache_policy = - IPR_DEV_CACHE_WRITE_BACK; - else - ioa->dev[device_count].write_cache_policy = - IPR_DEV_CACHE_WRITE_THROUGH; - } - /* find array config data matching resource entry */ k = 0; for_each_qac_entry(common_record, qac_data) { @@ -7487,7 +7479,13 @@ int ipr_get_dev_attr(struct ipr_dev *dev attr->tcq_enabled = is_tagged(dev); attr->format_timeout = get_format_timeout(dev); - attr->write_cache_policy = dev->write_cache_policy; + + if (ipr_is_gscsi(dev) || ipr_is_volume_set(dev)) { + if (ipr_dev_wcache_policy(dev) == IPR_DEV_CACHE_WRITE_BACK) + attr->write_cache_policy = IPR_DEV_CACHE_WRITE_BACK; + else + attr->write_cache_policy = IPR_DEV_CACHE_WRITE_THROUGH; + } return 0; } @@ -7655,6 +7653,8 @@ int ipr_modify_dev_attr(struct ipr_dev * rc = ipr_get_saved_dev_attr(dev, IPR_WRITE_CACHE_POLICY, temp); if (rc == RC_SUCCESS) sscanf(temp, "%d", &attr->write_cache_policy); + else + attr->write_cache_policy = IPR_DEV_CACHE_WRITE_BACK; return 0; } @@ -7738,12 +7738,14 @@ int ipr_set_dev_attr(struct ipr_dev *dev } } - if (attr->write_cache_policy != old_attr.write_cache_policy - || !attr->write_cache_policy) { - ipr_set_dev_wcache_policy(dev, attr->write_cache_policy); - if (save) { - sprintf(temp, "%d", attr->write_cache_policy); - ipr_save_dev_attr(dev, IPR_WRITE_CACHE_POLICY, temp, 1); + if (ipr_is_gscsi(dev) || ipr_is_volume_set(dev)) { + if (attr->write_cache_policy != old_attr.write_cache_policy + || !attr->write_cache_policy) { + ipr_set_dev_wcache_policy(dev, attr->write_cache_policy); + if (save) { + sprintf(temp, "%d", attr->write_cache_policy); + ipr_save_dev_attr(dev, IPR_WRITE_CACHE_POLICY, temp, 1); + } } } @@ -9723,11 +9725,6 @@ static void init_gpdd_dev(struct ipr_dev if (ipr_modify_dev_attr(dev, &attr)) return; - rc = ipr_get_saved_dev_attr(dev, IPR_WRITE_CACHE_POLICY, saved_cache); - policy = (rc || strtoul (saved_cache, NULL, 10)) ? - IPR_DEV_CACHE_WRITE_BACK : IPR_DEV_CACHE_WRITE_THROUGH; - ipr_set_dev_wcache_policy(dev, policy); - if (ipr_set_dev_attr(dev, &attr, 0)) return; } _ ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot _______________________________________________ Iprdd-devel mailing list Iprdd-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/iprdd-devel