[patch 6/6] statistics infrastructure - exploitation: zfcp

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



[patch 6/6] statistics infrastructure - exploitation: zfcp

This patch instruments the zfcp driver and makes it feed statistics data
into the statistics infrastructure.

Signed-off-by: Martin Peschke <[email protected]>
Acked-by: Andreas Herrmann <[email protected]>
---

 Makefile    |    4 -
 zfcp_aux.c  |   22 ++++++
 zfcp_ccw.c  |    7 ++
 zfcp_def.h  |   31 ++++++++-
 zfcp_erp.c  |    4 +
 zfcp_ext.h  |    6 +
 zfcp_fsf.c  |   60 +++++++++++++++++-
 zfcp_qdio.c |    5 +
 zfcp_scsi.c |   14 ++++
 zfcp_stat.c |  195 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 10 files changed, 338 insertions(+), 10 deletions(-)

diff -Nurp f/drivers/s390/scsi/Makefile g/drivers/s390/scsi/Makefile
--- f/drivers/s390/scsi/Makefile	2005-10-28 02:02:08.000000000 +0200
+++ g/drivers/s390/scsi/Makefile	2005-12-14 16:01:55.000000000 +0100
@@ -3,7 +3,7 @@
 #

 zfcp-objs := zfcp_aux.o zfcp_ccw.o zfcp_scsi.o zfcp_erp.o zfcp_qdio.o \
-	     zfcp_fsf.o zfcp_dbf.o zfcp_sysfs_adapter.o zfcp_sysfs_port.o \
-	     zfcp_sysfs_unit.o zfcp_sysfs_driver.o
+	     zfcp_fsf.o zfcp_dbf.o zfcp_stat.o zfcp_sysfs_adapter.o \
+	     zfcp_sysfs_port.o zfcp_sysfs_unit.o zfcp_sysfs_driver.o

 obj-$(CONFIG_ZFCP) += zfcp.o
diff -Nurp f/drivers/s390/scsi/zfcp_aux.c g/drivers/s390/scsi/zfcp_aux.c
--- f/drivers/s390/scsi/zfcp_aux.c	2005-12-14 12:51:26.000000000 +0100
+++ g/drivers/s390/scsi/zfcp_aux.c	2005-12-14 16:01:55.000000000 +0100
@@ -778,15 +778,20 @@ zfcp_unit_enqueue(struct zfcp_port *port
 	unit->sysfs_device.release = zfcp_sysfs_unit_release;
 	dev_set_drvdata(&unit->sysfs_device, unit);

+	if (zfcp_unit_statistic_register(unit))
+		return NULL;
+
 	/* mark unit unusable as long as sysfs registration is not complete */
 	atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &unit->status);

 	if (device_register(&unit->sysfs_device)) {
+		zfcp_unit_statistic_unregister(unit);
 		kfree(unit);
 		return NULL;
 	}

 	if (zfcp_sysfs_unit_create_files(&unit->sysfs_device)) {
+		zfcp_unit_statistic_unregister(unit);
 		device_unregister(&unit->sysfs_device);
 		return NULL;
 	}
@@ -826,6 +831,7 @@ zfcp_unit_dequeue(struct zfcp_unit *unit
 	list_del(&unit->list);
 	write_unlock_irq(&zfcp_data.config_lock);
 	unit->port->units--;
+	zfcp_unit_statistic_unregister(unit);
 	zfcp_port_put(unit->port);
 	zfcp_sysfs_unit_remove_files(&unit->sysfs_device);
 	device_unregister(&unit->sysfs_device);
@@ -837,6 +843,16 @@ zfcp_mempool_alloc(gfp_t gfp_mask, void
 	return kmalloc((size_t) size, gfp_mask);
 }

+static void *
+zfcp_mempool_alloc_fsf_req_scsi(unsigned int __nocast gfp_mask, void *data)
+{
+	struct zfcp_adapter *adapter = (struct zfcp_adapter *)data;
+	void *ptr = kmalloc(sizeof(struct zfcp_fsf_req_pool_element), gfp_mask);
+	if (!ptr)
+		statistic_inc(adapter->stat_low_mem_scsi, 0);
+	return ptr;
+}
+
 static void
 zfcp_mempool_free(void *element, void *size)
 {
@@ -864,8 +880,8 @@ zfcp_allocate_low_mem_buffers(struct zfc

 	adapter->pool.fsf_req_scsi =
 		mempool_create(ZFCP_POOL_FSF_REQ_SCSI_NR,
-			       zfcp_mempool_alloc, zfcp_mempool_free, (void *)
-			       sizeof(struct zfcp_fsf_req_pool_element));
+			       zfcp_mempool_alloc_fsf_req_scsi,
+			       zfcp_mempool_free, (void *)adapter);

 	if (NULL == adapter->pool.fsf_req_scsi)
 		return -ENOMEM;
diff -Nurp f/drivers/s390/scsi/zfcp_ccw.c g/drivers/s390/scsi/zfcp_ccw.c
--- f/drivers/s390/scsi/zfcp_ccw.c	2005-10-28 02:02:08.000000000 +0200
+++ g/drivers/s390/scsi/zfcp_ccw.c	2005-12-14 16:01:55.000000000 +0100
@@ -163,6 +163,10 @@ zfcp_ccw_set_online(struct ccw_device *c
 	retval = zfcp_adapter_debug_register(adapter);
 	if (retval)
 		goto out;
+	retval = zfcp_adapter_statistic_register(adapter);
+	if (retval)
+		goto out_stat_create;
+
 	retval = zfcp_erp_thread_setup(adapter);
 	if (retval) {
 		ZFCP_LOG_INFO("error: start of error recovery thread for "
@@ -183,6 +187,8 @@ zfcp_ccw_set_online(struct ccw_device *c
  out_scsi_register:
 	zfcp_erp_thread_kill(adapter);
  out_erp_thread:
+	zfcp_adapter_statistic_unregister(adapter);
+ out_stat_create:
 	zfcp_adapter_debug_unregister(adapter);
  out:
 	up(&zfcp_data.config_sema);
@@ -209,6 +215,7 @@ zfcp_ccw_set_offline(struct ccw_device *
 	zfcp_erp_wait(adapter);
 	zfcp_adapter_scsi_unregister(adapter);
 	zfcp_erp_thread_kill(adapter);
+	zfcp_adapter_statistic_unregister(adapter);
 	zfcp_adapter_debug_unregister(adapter);
 	up(&zfcp_data.config_sema);
 	return 0;
diff -Nurp f/drivers/s390/scsi/zfcp_def.h g/drivers/s390/scsi/zfcp_def.h
--- f/drivers/s390/scsi/zfcp_def.h	2005-10-28 02:02:08.000000000 +0200
+++ g/drivers/s390/scsi/zfcp_def.h	2005-12-14 16:01:55.000000000 +0100
@@ -58,6 +58,8 @@
 #include <asm/qdio.h>
 #include <asm/debug.h>
 #include <asm/ebcdic.h>
+#include <asm/timex.h>
+#include <linux/statistic.h>
 #include <linux/mempool.h>
 #include <linux/syscalls.h>
 #include <linux/ioctl.h>
@@ -66,7 +68,7 @@
 /********************* GENERAL DEFINES *********************************/

 /* zfcp version number, it consists of major, minor, and patch-level number */
-#define ZFCP_VERSION		"4.5.0"
+#define ZFCP_VERSION		"4.6.0"

 /**
  * zfcp_sg_to_address - determine kernel address from struct scatterlist
@@ -978,6 +980,12 @@ struct zfcp_adapter {
 	struct zfcp_adapter_mempool	pool;      /* Adapter memory pools */
 	struct qdio_initialize  qdio_init_data;    /* for qdio_establish */
 	struct device           generic_services;  /* directory for WKA ports */
+	struct statistic_interface	*stat_if;
+	struct statistic		*stat_qdio_outb_full;
+	struct statistic		*stat_qdio_outb;
+	struct statistic		*stat_qdio_inb;
+	struct statistic		*stat_low_mem_scsi;
+	struct statistic		*stat_erp;
 };

 /*
@@ -1024,6 +1032,24 @@ struct zfcp_unit {
         struct scsi_device     *device;        /* scsi device struct pointer */
 	struct zfcp_erp_action erp_action;     /* pending error recovery */
         atomic_t               erp_counter;
+	atomic_t		read_num;
+	atomic_t		write_num;
+	struct statistic_interface	*stat_if;
+	struct statistic		*stat_sizes_scsi_write;
+	struct statistic		*stat_sizes_scsi_read;
+	struct statistic		*stat_sizes_scsi_nodata;
+	struct statistic		*stat_sizes_scsi_nofit;
+	struct statistic		*stat_sizes_scsi_nomem;
+	struct statistic		*stat_sizes_timedout_write;
+	struct statistic		*stat_sizes_timedout_read;
+	struct statistic		*stat_sizes_timedout_nodata;
+	struct statistic		*stat_latencies_scsi_write;
+	struct statistic		*stat_latencies_scsi_read;
+	struct statistic		*stat_latencies_scsi_nodata;
+	struct statistic		*stat_pending_scsi_write;
+	struct statistic		*stat_pending_scsi_read;
+	struct statistic		*stat_erp;
+	struct statistic		*stat_eh_reset;
 };

 /* FSF request */
@@ -1050,7 +1076,8 @@ struct zfcp_fsf_req {
 	mempool_t	       *pool;	       /* used if request was alloacted
 						  from emergency pool */
 	unsigned long long     issued;         /* request sent time (STCK) */
-	struct zfcp_unit       *unit;
+	unsigned long long	received;
+	struct zfcp_unit	*unit;
 };

 typedef void zfcp_fsf_req_handler_t(struct zfcp_fsf_req*);
diff -Nurp f/drivers/s390/scsi/zfcp_erp.c g/drivers/s390/scsi/zfcp_erp.c
--- f/drivers/s390/scsi/zfcp_erp.c	2005-12-14 12:51:26.000000000 +0100
+++ g/drivers/s390/scsi/zfcp_erp.c	2005-12-14 16:01:55.000000000 +0100
@@ -1624,10 +1624,12 @@ zfcp_erp_strategy_check_unit(struct zfcp
 	switch (result) {
 	case ZFCP_ERP_SUCCEEDED :
 		atomic_set(&unit->erp_counter, 0);
+		statistic_inc(unit->stat_erp, 1);
 		zfcp_erp_unit_unblock(unit);
 		break;
 	case ZFCP_ERP_FAILED :
 		atomic_inc(&unit->erp_counter);
+		statistic_inc(unit->stat_erp, -1);
 		if (atomic_read(&unit->erp_counter) > ZFCP_MAX_ERPS)
 			zfcp_erp_unit_failed(unit);
 		break;
@@ -1695,10 +1697,12 @@ zfcp_erp_strategy_check_adapter(struct z
 	switch (result) {
 	case ZFCP_ERP_SUCCEEDED :
 		atomic_set(&adapter->erp_counter, 0);
+		statistic_inc(adapter->stat_erp, 1);
 		zfcp_erp_adapter_unblock(adapter);
 		break;
 	case ZFCP_ERP_FAILED :
 		atomic_inc(&adapter->erp_counter);
+		statistic_inc(adapter->stat_erp, -1);
 		if (atomic_read(&adapter->erp_counter) > ZFCP_MAX_ERPS)
 			zfcp_erp_adapter_failed(adapter);
 		break;
diff -Nurp f/drivers/s390/scsi/zfcp_ext.h g/drivers/s390/scsi/zfcp_ext.h
--- f/drivers/s390/scsi/zfcp_ext.h	2005-10-28 02:02:08.000000000 +0200
+++ g/drivers/s390/scsi/zfcp_ext.h	2005-12-14 16:01:55.000000000 +0100
@@ -203,4 +203,10 @@ extern void zfcp_scsi_dbf_event_abort(co
 extern void zfcp_scsi_dbf_event_devreset(const char *, u8, struct zfcp_unit *,
 					 struct scsi_cmnd *);

+/*************************** stat ********************************************/
+extern int zfcp_adapter_statistic_register(struct zfcp_adapter *);
+extern int zfcp_adapter_statistic_unregister(struct zfcp_adapter *);
+extern int zfcp_unit_statistic_register(struct zfcp_unit *);
+extern int zfcp_unit_statistic_unregister(struct zfcp_unit *);
+
 #endif	/* ZFCP_EXT_H */
diff -Nurp f/drivers/s390/scsi/zfcp_fsf.c g/drivers/s390/scsi/zfcp_fsf.c
--- f/drivers/s390/scsi/zfcp_fsf.c	2005-12-14 12:51:26.000000000 +0100
+++ g/drivers/s390/scsi/zfcp_fsf.c	2005-12-14 16:01:55.000000000 +0100
@@ -219,6 +219,8 @@ zfcp_fsf_req_complete(struct zfcp_fsf_re
 	int retval = 0;
 	int cleanup;

+	fsf_req->received = get_clock();
+
 	if (unlikely(fsf_req->fsf_command == FSF_QTCB_UNSOLICITED_STATUS)) {
 		ZFCP_LOG_DEBUG("Status read response received\n");
 		/*
@@ -3471,6 +3473,12 @@ zfcp_fsf_send_fcp_command_task(struct zf
 			       unit->fcp_lun,
 			       unit->port->wwpn,
 			       zfcp_get_busid_by_adapter(adapter));
+		if (retval == -ENOMEM)
+			statistic_inc(unit->stat_sizes_scsi_nomem,
+				       scsi_cmnd->request_bufflen);
+		if (retval == -EIO)
+			statistic_inc(unit->stat_sizes_scsi_nofit,
+				       scsi_cmnd->request_bufflen);
 		goto failed_req_create;
 	}

@@ -3581,6 +3589,8 @@ zfcp_fsf_send_fcp_command_task(struct zf
 		zfcp_erp_unit_shutdown(unit, 0);
 		retval = -EINVAL;
 		}
+		statistic_inc(unit->stat_sizes_scsi_nofit,
+			       scsi_cmnd->request_bufflen);
 		goto no_fit;
 	}

@@ -3591,6 +3601,13 @@ zfcp_fsf_send_fcp_command_task(struct zf
 	ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG,
 		      (char *) scsi_cmnd->cmnd, scsi_cmnd->cmd_len);

+	if (scsi_cmnd->sc_data_direction == DMA_FROM_DEVICE)
+		statistic_inc(unit->stat_pending_scsi_read,
+				atomic_inc_return(&unit->read_num));
+	else if (scsi_cmnd->sc_data_direction == DMA_TO_DEVICE)
+		statistic_inc(unit->stat_pending_scsi_write,
+				atomic_inc_return(&unit->write_num));
+
 	/*
 	 * start QDIO request for this FSF request
 	 *  covered by an SBALE)
@@ -3613,6 +3630,11 @@ zfcp_fsf_send_fcp_command_task(struct zf
 	goto success;

  send_failed:
+	if (scsi_cmnd->sc_data_direction == DMA_FROM_DEVICE)
+		atomic_dec(&unit->read_num);
+	else if (scsi_cmnd->sc_data_direction == DMA_TO_DEVICE)
+		atomic_dec(&unit->write_num);
+
  no_fit:
  failed_scsi_cmnd:
 	zfcp_unit_put(unit);
@@ -3984,9 +4006,32 @@ zfcp_fsf_send_fcp_command_task_handler(s
 	u32 sns_len;
 	char *fcp_rsp_info = zfcp_get_fcp_rsp_info_ptr(fcp_rsp_iu);
 	unsigned long flags;
+	struct zfcp_adapter *adapter = fsf_req->adapter;
 	struct zfcp_unit *unit = fsf_req->unit;
+	long long unsigned latency;

-	read_lock_irqsave(&fsf_req->adapter->abort_lock, flags);
+	statistic_lock(unit->stat_if, flags);
+	latency = fsf_req->received - fsf_req->issued;
+	do_div(latency, 1000000);
+	latency++;
+	if (fcp_cmnd_iu->wddata == 1) {
+		statistic_inc_nolock(unit->stat_sizes_scsi_write,
+				      zfcp_get_fcp_dl(fcp_cmnd_iu));
+		statistic_inc_nolock(unit->stat_latencies_scsi_write, latency);
+		atomic_dec(&unit->write_num);
+	} else if (fcp_cmnd_iu->rddata == 1) {
+		statistic_inc_nolock(unit->stat_sizes_scsi_read,
+				      zfcp_get_fcp_dl(fcp_cmnd_iu));
+		statistic_inc_nolock(unit->stat_latencies_scsi_read, latency);
+		atomic_dec(&unit->read_num);
+	} else {
+		statistic_inc_nolock(unit->stat_sizes_scsi_nodata,
+				      zfcp_get_fcp_dl(fcp_cmnd_iu));
+		statistic_inc_nolock(unit->stat_latencies_scsi_nodata, latency);
+	}
+	statistic_unlock(unit->stat_if, flags);
+
+	read_lock_irqsave(&adapter->abort_lock, flags);
 	scpnt = (struct scsi_cmnd *) fsf_req->data;
 	if (unlikely(!scpnt)) {
 		ZFCP_LOG_DEBUG
@@ -4188,7 +4233,7 @@ zfcp_fsf_send_fcp_command_task_handler(s
 	 * Note: scsi_done must not block!
 	 */
  out:
-	read_unlock_irqrestore(&fsf_req->adapter->abort_lock, flags);
+	read_unlock_irqrestore(&adapter->abort_lock, flags);
 	return retval;
 }

@@ -4605,10 +4650,14 @@ zfcp_fsf_req_sbal_get(struct zfcp_adapte
 						       ZFCP_SBAL_TIMEOUT);
 		if (ret < 0)
 			return ret;
-		if (!ret)
+		if (!ret) {
+			statistic_inc(adapter->stat_qdio_outb_full, 1);
 			return -EIO;
-        } else if (!zfcp_fsf_req_sbal_check(lock_flags, req_queue, 1))
+		}
+        } else if (!zfcp_fsf_req_sbal_check(lock_flags, req_queue, 1)) {
+		statistic_inc(adapter->stat_qdio_outb_full, 1);
                 return -EIO;
+	}

         return 0;
 }
@@ -4774,6 +4823,9 @@ zfcp_fsf_req_send(struct zfcp_fsf_req *f
 	 * position of first one
 	 */
 	atomic_sub(fsf_req->sbal_number, &req_queue->free_count);
+	statistic_inc(adapter->stat_qdio_outb,
+			QDIO_MAX_BUFFERS_PER_Q -
+			atomic_read(&req_queue->free_count));
 	ZFCP_LOG_TRACE("free_count=%d\n", atomic_read(&req_queue->free_count));
 	req_queue->free_index += fsf_req->sbal_number;	  /* increase */
 	req_queue->free_index %= QDIO_MAX_BUFFERS_PER_Q;  /* wrap if needed */
diff -Nurp f/drivers/s390/scsi/zfcp_qdio.c g/drivers/s390/scsi/zfcp_qdio.c
--- f/drivers/s390/scsi/zfcp_qdio.c	2005-10-28 02:02:08.000000000 +0200
+++ g/drivers/s390/scsi/zfcp_qdio.c	2005-12-14 16:01:55.000000000 +0100
@@ -418,6 +418,7 @@ zfcp_qdio_response_handler(struct ccw_de
 	} else {
 		queue->free_index += count;
 		queue->free_index %= QDIO_MAX_BUFFERS_PER_Q;
+		statistic_inc(adapter->stat_qdio_inb, count);
 		atomic_set(&queue->free_count, 0);
 		ZFCP_LOG_TRACE("%i buffers enqueued to response "
 			       "queue at position %i\n", count, start);
@@ -662,6 +663,10 @@ zfcp_qdio_sbals_from_segment(struct zfcp
 		/* get next free SBALE for new piece */
 		if (NULL == zfcp_qdio_sbale_next(fsf_req, sbtype)) {
 			/* no SBALE left, clean up and leave */
+			statistic_inc(
+				fsf_req->adapter->stat_qdio_outb_full,
+				atomic_read(
+				 &fsf_req->adapter->request_queue.free_count));
 			zfcp_qdio_sbals_wipe(fsf_req);
 			return -EINVAL;
 		}
diff -Nurp f/drivers/s390/scsi/zfcp_scsi.c g/drivers/s390/scsi/zfcp_scsi.c
--- f/drivers/s390/scsi/zfcp_scsi.c	2005-12-14 12:51:26.000000000 +0100
+++ g/drivers/s390/scsi/zfcp_scsi.c	2005-12-14 16:01:55.000000000 +0100
@@ -449,6 +449,16 @@ zfcp_scsi_eh_abort_handler(struct scsi_c
 	ZFCP_LOG_INFO("aborting scsi_cmnd=%p on adapter %s\n",
 		      scpnt, zfcp_get_busid_by_adapter(adapter));

+	if (scpnt->sc_data_direction == DMA_TO_DEVICE)
+		statistic_inc(unit->stat_sizes_timedout_write,
+			      scpnt->request_bufflen);
+	else if (scpnt->sc_data_direction == DMA_FROM_DEVICE)
+		statistic_inc(unit->stat_sizes_timedout_read,
+			      scpnt->request_bufflen);
+	else
+		statistic_inc(unit->stat_sizes_timedout_nodata,
+			       scpnt->request_bufflen);
+
 	/* avoid race condition between late normal completion and abort */
 	write_lock_irqsave(&adapter->abort_lock, flags);

@@ -538,12 +548,14 @@ zfcp_scsi_eh_device_reset_handler(struct
 				atomic_set_mask
 				    (ZFCP_STATUS_UNIT_NOTSUPPUNITRESET,
 				     &unit->status);
+			statistic_inc(unit->stat_eh_reset, -1);
 			/* fall through and try 'target reset' next */
 		} else {
 			ZFCP_LOG_DEBUG("unit reset succeeded (unit=%p)\n",
 				       unit);
 			/* avoid 'target reset' */
 			retval = SUCCESS;
+			statistic_inc(unit->stat_eh_reset, 1);
 			goto out;
 		}
 	}
@@ -551,9 +563,11 @@ zfcp_scsi_eh_device_reset_handler(struct
 	if (retval) {
 		ZFCP_LOG_DEBUG("target reset failed (unit=%p)\n", unit);
 		retval = FAILED;
+		statistic_inc(unit->stat_eh_reset, -2);
 	} else {
 		ZFCP_LOG_DEBUG("target reset succeeded (unit=%p)\n", unit);
 		retval = SUCCESS;
+		statistic_inc(unit->stat_eh_reset, 2);
 	}
  out:
 	return retval;
diff -Nurp f/drivers/s390/scsi/zfcp_stat.c g/drivers/s390/scsi/zfcp_stat.c
--- f/drivers/s390/scsi/zfcp_stat.c	1970-01-01 01:00:00.000000000 +0100
+++ g/drivers/s390/scsi/zfcp_stat.c	2005-12-14 16:01:55.000000000 +0100
@@ -0,0 +1,195 @@
+/*
+ *
+ * linux/drivers/s390/scsi/zfcp_stat.c
+ *
+ * FCP adapter driver for IBM eServer zSeries
+ *
+ * Statistics
+ *
+ * (C) Copyright IBM Corp. 2005
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#define ZFCP_STAT_REVISION "$Revision: 1.9 $"
+
+#include <linux/statistic.h>
+#include <linux/ctype.h>
+#include "zfcp_ext.h"
+
+#define ZFCP_LOG_AREA			ZFCP_LOG_AREA_OTHER
+
+int zfcp_adapter_statistic_register(struct zfcp_adapter *adapter)
+{
+	int retval = 0;
+	char name[14];
+
+	sprintf(name, "zfcp-%s", zfcp_get_busid_by_adapter(adapter));
+	statistic_interface_create(&adapter->stat_if, name);
+
+	retval |=
+	    statistic_create(&adapter->stat_qdio_outb_full, adapter->stat_if,
+			     "occurrence_qdio_outb_full",
+			     "sbals_left/incidents");
+	statistic_define_value(adapter->stat_qdio_outb_full,
+			       STATISTIC_RANGE_MIN, STATISTIC_RANGE_MAX,
+			       STATISTIC_DEF_MODE_INC);
+
+	retval |= statistic_create(&adapter->stat_qdio_outb, adapter->stat_if,
+				   "util_qdio_outb",
+				   "slots-occupied/incidents");
+	statistic_define_range(adapter->stat_qdio_outb,
+			       0, QDIO_MAX_BUFFERS_PER_Q);
+
+	retval |= statistic_create(&adapter->stat_qdio_inb, adapter->stat_if,
+				   "util_qdio_inb", "slots-occupied/incidents");
+	statistic_define_range(adapter->stat_qdio_inb,
+			       0, QDIO_MAX_BUFFERS_PER_Q);
+
+	retval |=
+	    statistic_create(&adapter->stat_low_mem_scsi, adapter->stat_if,
+			     "occurrence_low_mem_scsi", "-/incidents");
+	statistic_define_value(adapter->stat_low_mem_scsi, STATISTIC_RANGE_MIN,
+			       STATISTIC_RANGE_MAX, STATISTIC_DEF_MODE_INC);
+
+	retval |= statistic_create(&adapter->stat_erp, adapter->stat_if,
+				   "occurrence_erp", "results/incidents");
+	statistic_define_value(adapter->stat_erp,
+			       STATISTIC_RANGE_MIN, STATISTIC_RANGE_MAX,
+			       STATISTIC_DEF_MODE_INC);
+
+	return retval;
+}
+
+int zfcp_adapter_statistic_unregister(struct zfcp_adapter *adapter)
+{
+	return statistic_interface_remove(&adapter->stat_if);
+}
+
+int zfcp_unit_statistic_register(struct zfcp_unit *unit)
+{
+	int retval = 0;
+	char name[64];
+
+	atomic_set(&unit->read_num, 0);
+	atomic_set(&unit->write_num, 0);
+
+	sprintf(name, "zfcp-%s-0x%016Lx-0x%016Lx",
+		zfcp_get_busid_by_unit(unit), unit->port->wwpn, unit->fcp_lun);
+	statistic_interface_create(&unit->stat_if, name);
+
+	retval |= statistic_create(&unit->stat_sizes_scsi_write, unit->stat_if,
+				   "request_sizes_scsi_write",
+				   "bytes/incidents");
+	statistic_define_list(unit->stat_sizes_scsi_write, 0,
+			      STATISTIC_RANGE_MAX, 256);
+
+	retval |= statistic_create(&unit->stat_sizes_scsi_read, unit->stat_if,
+				   "request_sizes_scsi_read",
+				   "bytes/incidents");
+	statistic_define_list(unit->stat_sizes_scsi_read, 0,
+			      STATISTIC_RANGE_MAX, 256);
+
+	retval |= statistic_create(&unit->stat_sizes_scsi_nodata, unit->stat_if,
+				   "request_sizes_scsi_nodata",
+				   "bytes/incidents");
+	statistic_define_value(unit->stat_sizes_scsi_nodata,
+			       STATISTIC_RANGE_MIN, STATISTIC_RANGE_MAX,
+			       STATISTIC_DEF_MODE_INC);
+
+	retval |= statistic_create(&unit->stat_sizes_scsi_nofit, unit->stat_if,
+				   "request_sizes_scsi_nofit",
+				   "bytes/incidents");
+	statistic_define_list(unit->stat_sizes_scsi_nofit, 0,
+			      STATISTIC_RANGE_MAX, 256);
+
+	retval |= statistic_create(&unit->stat_sizes_scsi_nomem, unit->stat_if,
+				   "request_sizes_scsi_nomem",
+				   "bytes/incidents");
+	statistic_define_value(unit->stat_sizes_scsi_nomem, STATISTIC_RANGE_MIN,
+			       STATISTIC_RANGE_MAX, STATISTIC_DEF_MODE_INC);
+
+	retval |=
+	    statistic_create(&unit->stat_sizes_timedout_write, unit->stat_if,
+			     "request_sizes_timedout_write", "bytes/incidents");
+	statistic_define_value(unit->stat_sizes_timedout_write,
+			       STATISTIC_RANGE_MIN, STATISTIC_RANGE_MAX,
+			       STATISTIC_DEF_MODE_INC);
+
+	retval |=
+	    statistic_create(&unit->stat_sizes_timedout_read, unit->stat_if,
+			     "request_sizes_timedout_read", "bytes/incidents");
+	statistic_define_value(unit->stat_sizes_timedout_read,
+			       STATISTIC_RANGE_MIN, STATISTIC_RANGE_MAX,
+			       STATISTIC_DEF_MODE_INC);
+
+	retval |=
+	    statistic_create(&unit->stat_sizes_timedout_nodata, unit->stat_if,
+			     "request_sizes_timedout_nodata",
+			     "bytes/incidents");
+	statistic_define_value(unit->stat_sizes_timedout_nodata,
+			       STATISTIC_RANGE_MIN, STATISTIC_RANGE_MAX,
+			       STATISTIC_DEF_MODE_INC);
+
+	retval |=
+	    statistic_create(&unit->stat_latencies_scsi_write, unit->stat_if,
+			     "latencies_scsi_write", "milliseconds/incidents");
+	statistic_define_array(unit->stat_latencies_scsi_write, 0, 1024, 1,
+			       STATISTIC_DEF_SCALE_LOG2);
+
+	retval |=
+	    statistic_create(&unit->stat_latencies_scsi_read, unit->stat_if,
+			     "latencies_scsi_read", "milliseconds/incidents");
+	statistic_define_array(unit->stat_latencies_scsi_read, 0, 1024, 1,
+			       STATISTIC_DEF_SCALE_LOG2);
+
+	retval |=
+	    statistic_create(&unit->stat_latencies_scsi_nodata, unit->stat_if,
+			     "latencies_scsi_nodata", "milliseconds/incidents");
+	statistic_define_array(unit->stat_latencies_scsi_nodata, 0, 1024, 1,
+			       STATISTIC_DEF_SCALE_LOG2);
+
+	retval |=
+	    statistic_create(&unit->stat_pending_scsi_write, unit->stat_if,
+			     "pending_scsi_write", "commands/incidents");
+	statistic_define_range(unit->stat_pending_scsi_write, 0,
+			       STATISTIC_RANGE_MAX);
+
+	retval |= statistic_create(&unit->stat_pending_scsi_read, unit->stat_if,
+				   "pending_scsi_read", "commands/incidents");
+	statistic_define_range(unit->stat_pending_scsi_read, 0,
+			       STATISTIC_RANGE_MAX);
+
+	retval |= statistic_create(&unit->stat_erp, unit->stat_if,
+				   "occurrence_erp", "results/incidents");
+	statistic_define_value(unit->stat_erp,
+			       STATISTIC_RANGE_MIN, STATISTIC_RANGE_MAX,
+			       STATISTIC_DEF_MODE_INC);
+
+	retval |= statistic_create(&unit->stat_eh_reset, unit->stat_if,
+				   "occurrence_eh_reset", "results/incidents");
+	statistic_define_value(unit->stat_eh_reset,
+			       STATISTIC_RANGE_MIN, STATISTIC_RANGE_MAX,
+			       STATISTIC_DEF_MODE_INC);
+
+	return retval;
+}
+
+int zfcp_unit_statistic_unregister(struct zfcp_unit *unit)
+{
+	return statistic_interface_remove(&unit->stat_if);
+}
+
+#undef ZFCP_LOG_AREA
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux