Skip to content

Commit

Permalink
scsi: zfcp: move maximum age of diagnostic buffers into a per-adapter…
Browse files Browse the repository at this point in the history
… variable

Replace the static define (ZFCP_DIAG_MAX_AGE) with a per-adapter variable
(${adapter}->diagnostics->max_age). This new variable is exported via
sysfs, along with other, already existing adapter variables, and can both
be read and written. This way users can choose how much time should pass
between refreshes of diagnostic buffers. The default value for the age
remains to be five seconds.

By setting this new variable to 0, the caching of diagnostic buffers for
userspace accesses can also be completely removed.

All diagnostic buffers of a given adapter are subject to this setting in
the same way.

Link: https://lore.kernel.org/r/b1d0977cc884b16dd4ca6418e4320c56a4c31d63.1572018132.git.bblock@linux.ibm.com
Reviewed-by: Steffen Maier <maier@linux.ibm.com>
Signed-off-by: Benjamin Block <bblock@linux.ibm.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
  • Loading branch information
Benjamin-Block authored and martinkpetersen committed Oct 29, 2019
1 parent 8a72db7 commit 48910f8
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 11 deletions.
23 changes: 12 additions & 11 deletions drivers/s390/scsi/zfcp_diag.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,6 @@
#include "zfcp_ext.h"
#include "zfcp_def.h"

/* Max age of data in a diagnostics buffer before it needs a refresh (in ms). */
#define ZFCP_DIAG_MAX_AGE (5 * 1000)

static DECLARE_WAIT_QUEUE_HEAD(__zfcp_diag_publish_wait);

/**
Expand All @@ -38,31 +35,32 @@ static DECLARE_WAIT_QUEUE_HEAD(__zfcp_diag_publish_wait);
*/
int zfcp_diag_adapter_setup(struct zfcp_adapter *const adapter)
{
/* set the timestamp so that the first test on age will always fail */
const unsigned long initial_timestamp =
jiffies - msecs_to_jiffies(ZFCP_DIAG_MAX_AGE);
struct zfcp_diag_adapter *diag;
struct zfcp_diag_header *hdr;

diag = kzalloc(sizeof(*diag), GFP_KERNEL);
if (diag == NULL)
return -ENOMEM;

diag->max_age = (5 * 1000); /* default value: 5 s */

/* setup header for port_data */
hdr = &diag->port_data.header;

spin_lock_init(&hdr->access_lock);
hdr->buffer = &diag->port_data.data;
hdr->buffer_size = sizeof(diag->port_data.data);
hdr->timestamp = initial_timestamp;
/* set the timestamp so that the first test on age will always fail */
hdr->timestamp = jiffies - msecs_to_jiffies(diag->max_age);

/* setup header for config_data */
hdr = &diag->config_data.header;

spin_lock_init(&hdr->access_lock);
hdr->buffer = &diag->config_data.data;
hdr->buffer_size = sizeof(diag->config_data.data);
hdr->timestamp = initial_timestamp;
/* set the timestamp so that the first test on age will always fail */
hdr->timestamp = jiffies - msecs_to_jiffies(diag->max_age);

adapter->diagnostics = diag;
return 0;
Expand Down Expand Up @@ -240,7 +238,8 @@ static int __zfcp_diag_update_buffer(struct zfcp_adapter *const adapter,
}

static bool
__zfcp_diag_test_buffer_age_isfresh(const struct zfcp_diag_header *const hdr)
__zfcp_diag_test_buffer_age_isfresh(const struct zfcp_diag_adapter *const diag,
const struct zfcp_diag_header *const hdr)
__must_hold(hdr->access_lock)
{
const unsigned long now = jiffies;
Expand All @@ -252,7 +251,7 @@ __zfcp_diag_test_buffer_age_isfresh(const struct zfcp_diag_header *const hdr)
if (!time_after_eq(now, hdr->timestamp))
return false;

if (jiffies_to_msecs(now - hdr->timestamp) >= ZFCP_DIAG_MAX_AGE)
if (jiffies_to_msecs(now - hdr->timestamp) >= diag->max_age)
return false;

return true;
Expand Down Expand Up @@ -291,7 +290,9 @@ int zfcp_diag_update_buffer_limited(struct zfcp_adapter *const adapter,

spin_lock_irqsave(&hdr->access_lock, flags);

for (rc = 0; !__zfcp_diag_test_buffer_age_isfresh(hdr); rc = 0) {
for (rc = 0;
!__zfcp_diag_test_buffer_age_isfresh(adapter->diagnostics, hdr);
rc = 0) {
rc = __zfcp_diag_update_buffer(adapter, hdr, buffer_update,
&flags);
if (rc != -EAGAIN)
Expand Down
4 changes: 4 additions & 0 deletions drivers/s390/scsi/zfcp_diag.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ struct zfcp_diag_header {
* adapter.
* @sysfs_established: flag showing that the associated sysfs-group was created
* during run of zfcp_adapter_enqueue().
* @max_age: maximum age of data in diagnostic buffers before they need to be
* refreshed (in ms).
* @port_data: data retrieved using exchange port data.
* @port_data.header: header with metadata for the cache in @port_data.data.
* @port_data.data: cached QTCB Bottom of command exchange port data.
Expand All @@ -52,6 +54,8 @@ struct zfcp_diag_header {
struct zfcp_diag_adapter {
u64 sysfs_established :1;

unsigned long max_age;

struct {
struct zfcp_diag_header header;
struct fsf_qtcb_bottom_port data;
Expand Down
45 changes: 45 additions & 0 deletions drivers/s390/scsi/zfcp_sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,50 @@ static ssize_t zfcp_sysfs_port_remove_store(struct device *dev,
static ZFCP_DEV_ATTR(adapter, port_remove, S_IWUSR, NULL,
zfcp_sysfs_port_remove_store);

static ssize_t
zfcp_sysfs_adapter_diag_max_age_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(to_ccwdev(dev));
ssize_t rc;

if (!adapter)
return -ENODEV;

/* ceil(log(2^64 - 1) / log(10)) = 20 */
rc = scnprintf(buf, 20 + 2, "%lu\n", adapter->diagnostics->max_age);

zfcp_ccw_adapter_put(adapter);
return rc;
}

static ssize_t
zfcp_sysfs_adapter_diag_max_age_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(to_ccwdev(dev));
unsigned long max_age;
ssize_t rc;

if (!adapter)
return -ENODEV;

rc = kstrtoul(buf, 10, &max_age);
if (rc != 0)
goto out;

adapter->diagnostics->max_age = max_age;

rc = count;
out:
zfcp_ccw_adapter_put(adapter);
return rc;
}
static ZFCP_DEV_ATTR(adapter, diag_max_age, 0644,
zfcp_sysfs_adapter_diag_max_age_show,
zfcp_sysfs_adapter_diag_max_age_store);

static struct attribute *zfcp_adapter_attrs[] = {
&dev_attr_adapter_failed.attr,
&dev_attr_adapter_in_recovery.attr,
Expand All @@ -338,6 +382,7 @@ static struct attribute *zfcp_adapter_attrs[] = {
&dev_attr_adapter_lic_version.attr,
&dev_attr_adapter_status.attr,
&dev_attr_adapter_hardware_version.attr,
&dev_attr_adapter_diag_max_age.attr,
NULL
};

Expand Down

0 comments on commit 48910f8

Please sign in to comment.