Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 22f99347 authored by Jan Glauber's avatar Jan Glauber Committed by Martin Schwidefsky
Browse files

[S390] qdio: rework debug feature logging



- make qdio_trace a per device view
- remove s390dbf exceptions
- remove CONFIG_QDIO_DEBUG, not needed anymore if we check for the level
  before calling sprintf
- use snprintf for dbf entries
- add start markers to see if the dbf view wrapped
- add a global error view for all queues

Signed-off-by: default avatarJan Glauber <jang@linux.vnet.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent 9a1ce28a
Loading
Loading
Loading
Loading
+0 −10
Original line number Original line Diff line number Diff line
@@ -347,16 +347,6 @@ config QDIO


	  If unsure, say Y.
	  If unsure, say Y.


config QDIO_DEBUG
	bool "Extended debugging information"
	depends on QDIO
	help
	  Say Y here to get extended debugging output in
	    /sys/kernel/debug/s390dbf/qdio...
	  Warning: this option reduces the performance of the QDIO module.

	  If unsure, say N.

config CHSC_SCH
config CHSC_SCH
	tristate "Support for CHSC subchannels"
	tristate "Support for CHSC subchannels"
	help
	help
+3 −0
Original line number Original line Diff line number Diff line
@@ -10,6 +10,7 @@


#include <asm/page.h>
#include <asm/page.h>
#include <asm/schid.h>
#include <asm/schid.h>
#include <asm/debug.h>
#include "chsc.h"
#include "chsc.h"


#define QDIO_BUSY_BIT_PATIENCE		100	/* 100 microseconds */
#define QDIO_BUSY_BIT_PATIENCE		100	/* 100 microseconds */
@@ -300,11 +301,13 @@ struct qdio_irq {
	struct qdio_q *input_qs[QDIO_MAX_QUEUES_PER_IRQ];
	struct qdio_q *input_qs[QDIO_MAX_QUEUES_PER_IRQ];
	struct qdio_q *output_qs[QDIO_MAX_QUEUES_PER_IRQ];
	struct qdio_q *output_qs[QDIO_MAX_QUEUES_PER_IRQ];


	debug_info_t *debug_area;
	struct mutex setup_mutex;
	struct mutex setup_mutex;
};
};


/* helper functions */
/* helper functions */
#define queue_type(q)	q->irq_ptr->qib.qfmt
#define queue_type(q)	q->irq_ptr->qib.qfmt
#define SCH_NO(q)	(q->irq_ptr->schid.sch_no)


#define is_thinint_irq(irq) \
#define is_thinint_irq(irq) \
	(irq->qib.qfmt == QDIO_IQDIO_QFMT || \
	(irq->qib.qfmt == QDIO_IQDIO_QFMT || \
+42 −55
Original line number Original line Diff line number Diff line
@@ -14,7 +14,7 @@
#include "qdio.h"
#include "qdio.h"


debug_info_t *qdio_dbf_setup;
debug_info_t *qdio_dbf_setup;
debug_info_t *qdio_dbf_trace;
debug_info_t *qdio_dbf_error;


static struct dentry *debugfs_root;
static struct dentry *debugfs_root;
#define MAX_DEBUGFS_QUEUES	32
#define MAX_DEBUGFS_QUEUES	32
@@ -22,59 +22,33 @@ static struct dentry *debugfs_queues[MAX_DEBUGFS_QUEUES] = { NULL };
static DEFINE_MUTEX(debugfs_mutex);
static DEFINE_MUTEX(debugfs_mutex);
#define QDIO_DEBUGFS_NAME_LEN	40
#define QDIO_DEBUGFS_NAME_LEN	40


void qdio_allocate_do_dbf(struct qdio_initialize *init_data)
void qdio_allocate_dbf(struct qdio_initialize *init_data,
		       struct qdio_irq *irq_ptr)
{
{
	char dbf_text[20];
	char text[20];


	sprintf(dbf_text, "qfmt:%x", init_data->q_format);
	DBF_EVENT("qfmt:%1d", init_data->q_format);
	QDIO_DBF_TEXT0(0, setup, dbf_text);
	DBF_HEX(init_data->adapter_name, 8);
	QDIO_DBF_HEX0(0, setup, init_data->adapter_name, 8);
	DBF_EVENT("qpff%4x", init_data->qib_param_field_format);
	sprintf(dbf_text, "qpff%4x", init_data->qib_param_field_format);
	DBF_HEX(&init_data->qib_param_field, sizeof(void *));
	QDIO_DBF_TEXT0(0, setup, dbf_text);
	DBF_HEX(&init_data->input_slib_elements, sizeof(void *));
	QDIO_DBF_HEX0(0, setup, &init_data->qib_param_field, sizeof(void *));
	DBF_HEX(&init_data->output_slib_elements, sizeof(void *));
	QDIO_DBF_HEX0(0, setup, &init_data->input_slib_elements, sizeof(void *));
	DBF_EVENT("niq:%1d noq:%1d", init_data->no_input_qs,
	QDIO_DBF_HEX0(0, setup, &init_data->output_slib_elements, sizeof(void *));
		  init_data->no_output_qs);
	sprintf(dbf_text, "niq:%4x", init_data->no_input_qs);
	DBF_HEX(&init_data->input_handler, sizeof(void *));
	QDIO_DBF_TEXT0(0, setup, dbf_text);
	DBF_HEX(&init_data->output_handler, sizeof(void *));
	sprintf(dbf_text, "noq:%4x", init_data->no_output_qs);
	DBF_HEX(&init_data->int_parm, sizeof(long));
	QDIO_DBF_TEXT0(0, setup, dbf_text);
	DBF_HEX(&init_data->flags, sizeof(long));
	QDIO_DBF_HEX0(0, setup, &init_data->input_handler, sizeof(void *));
	DBF_HEX(&init_data->input_sbal_addr_array, sizeof(void *));
	QDIO_DBF_HEX0(0, setup, &init_data->output_handler, sizeof(void *));
	DBF_HEX(&init_data->output_sbal_addr_array, sizeof(void *));
	QDIO_DBF_HEX0(0, setup, &init_data->int_parm, sizeof(long));
	DBF_EVENT("irq:%8lx", (unsigned long)irq_ptr);
	QDIO_DBF_HEX0(0, setup, &init_data->flags, sizeof(long));

	QDIO_DBF_HEX0(0, setup, &init_data->input_sbal_addr_array, sizeof(void *));
	/* allocate trace view for the interface */
	QDIO_DBF_HEX0(0, setup, &init_data->output_sbal_addr_array, sizeof(void *));
	snprintf(text, 20, "qdio_%s", dev_name(&init_data->cdev->dev));
}
	irq_ptr->debug_area = debug_register(text, 2, 1, 16);

	debug_register_view(irq_ptr->debug_area, &debug_hex_ascii_view);
static void qdio_unregister_dbf_views(void)
	debug_set_level(irq_ptr->debug_area, DBF_WARN);
{
	DBF_DEV_EVENT(DBF_ERR, irq_ptr, "dbf created");
	if (qdio_dbf_setup)
		debug_unregister(qdio_dbf_setup);
	if (qdio_dbf_trace)
		debug_unregister(qdio_dbf_trace);
}

static int qdio_register_dbf_views(void)
{
	qdio_dbf_setup = debug_register("qdio_setup", QDIO_DBF_SETUP_PAGES,
					QDIO_DBF_SETUP_NR_AREAS,
					QDIO_DBF_SETUP_LEN);
	if (!qdio_dbf_setup)
		goto oom;
	debug_register_view(qdio_dbf_setup, &debug_hex_ascii_view);
	debug_set_level(qdio_dbf_setup, QDIO_DBF_SETUP_LEVEL);

	qdio_dbf_trace = debug_register("qdio_trace", QDIO_DBF_TRACE_PAGES,
					QDIO_DBF_TRACE_NR_AREAS,
					QDIO_DBF_TRACE_LEN);
	if (!qdio_dbf_trace)
		goto oom;
	debug_register_view(qdio_dbf_trace, &debug_hex_ascii_view);
	debug_set_level(qdio_dbf_trace, QDIO_DBF_TRACE_LEVEL);
	return 0;
oom:
	qdio_unregister_dbf_views();
	return -ENOMEM;
}
}


static int qstat_show(struct seq_file *m, void *v)
static int qstat_show(struct seq_file *m, void *v)
@@ -223,11 +197,24 @@ void qdio_shutdown_debug_entries(struct qdio_irq *irq_ptr, struct ccw_device *cd
int __init qdio_debug_init(void)
int __init qdio_debug_init(void)
{
{
	debugfs_root = debugfs_create_dir("qdio_queues", NULL);
	debugfs_root = debugfs_create_dir("qdio_queues", NULL);
	return qdio_register_dbf_views();

	qdio_dbf_setup = debug_register("qdio_setup", 16, 1, 16);
	debug_register_view(qdio_dbf_setup, &debug_hex_ascii_view);
	debug_set_level(qdio_dbf_setup, DBF_INFO);
	DBF_EVENT("dbf created\n");

	qdio_dbf_error = debug_register("qdio_error", 4, 1, 16);
	debug_register_view(qdio_dbf_error, &debug_hex_ascii_view);
	debug_set_level(qdio_dbf_error, DBF_INFO);
	DBF_ERROR("dbf created\n");
	return 0;
}
}


void qdio_debug_exit(void)
void qdio_debug_exit(void)
{
{
	debugfs_remove(debugfs_root);
	debugfs_remove(debugfs_root);
	qdio_unregister_dbf_views();
	if (qdio_dbf_setup)
		debug_unregister(qdio_dbf_setup);
	if (qdio_dbf_error)
		debug_unregister(qdio_dbf_error);
}
}
+52 −60
Original line number Original line Diff line number Diff line
@@ -12,80 +12,72 @@
#include <asm/qdio.h>
#include <asm/qdio.h>
#include "qdio.h"
#include "qdio.h"


#define QDIO_DBF_HEX(ex, name, level, addr, len) \
/* that gives us 15 characters in the text event views */
#define QDIO_DBF_LEN	16

extern debug_info_t *qdio_dbf_setup;
extern debug_info_t *qdio_dbf_error;

/* sort out low debug levels early to avoid wasted sprints */
static inline int qdio_dbf_passes(debug_info_t *dbf_grp, int level)
{
	return (level <= dbf_grp->level);
}

#define DBF_ERR		3	/* error conditions	*/
#define DBF_WARN	4	/* warning conditions	*/
#define DBF_INFO	6	/* informational	*/

#undef DBF_EVENT
#undef DBF_ERROR
#undef DBF_DEV_EVENT

#define DBF_EVENT(text...) \
	do { \
	do { \
	if (ex) \
		char debug_buffer[QDIO_DBF_LEN]; \
		debug_exception(qdio_dbf_##name, level, (void *)(addr), len); \
		snprintf(debug_buffer, QDIO_DBF_LEN, text); \
	else \
		debug_text_event(qdio_dbf_setup, DBF_ERR, debug_buffer); \
		debug_event(qdio_dbf_##name, level, (void *)(addr), len); \
	} while (0)
	} while (0)
#define QDIO_DBF_TEXT(ex, name, level, text) \

#define DBF_HEX(addr, len) \
	do { \
	do { \
	if (ex) \
		debug_event(qdio_dbf_setup, DBF_ERR, (void*)(addr), len); \
		debug_text_exception(qdio_dbf_##name, level, text); \
	else \
		debug_text_event(qdio_dbf_##name, level, text); \
	} while (0)
	} while (0)


#define QDIO_DBF_HEX0(ex, name, addr, len) QDIO_DBF_HEX(ex, name, 0, addr, len)
#define DBF_ERROR(text...) \
#define QDIO_DBF_HEX1(ex, name, addr, len) QDIO_DBF_HEX(ex, name, 1, addr, len)
	do { \
#define QDIO_DBF_HEX2(ex, name, addr, len) QDIO_DBF_HEX(ex, name, 2, addr, len)
		char debug_buffer[QDIO_DBF_LEN]; \

		snprintf(debug_buffer, QDIO_DBF_LEN, text); \
#ifdef CONFIG_QDIO_DEBUG
		debug_text_event(qdio_dbf_error, DBF_ERR, debug_buffer); \
#define QDIO_DBF_HEX3(ex, name, addr, len) QDIO_DBF_HEX(ex, name, 3, addr, len)
	} while (0)
#define QDIO_DBF_HEX4(ex, name, addr, len) QDIO_DBF_HEX(ex, name, 4, addr, len)
#define QDIO_DBF_HEX5(ex, name, addr, len) QDIO_DBF_HEX(ex, name, 5, addr, len)
#define QDIO_DBF_HEX6(ex, name, addr, len) QDIO_DBF_HEX(ex, name, 6, addr, len)
#else
#define QDIO_DBF_HEX3(ex, name, addr, len) do {} while (0)
#define QDIO_DBF_HEX4(ex, name, addr, len) do {} while (0)
#define QDIO_DBF_HEX5(ex, name, addr, len) do {} while (0)
#define QDIO_DBF_HEX6(ex, name, addr, len) do {} while (0)
#endif /* CONFIG_QDIO_DEBUG */

#define QDIO_DBF_TEXT0(ex, name, text) QDIO_DBF_TEXT(ex, name, 0, text)
#define QDIO_DBF_TEXT1(ex, name, text) QDIO_DBF_TEXT(ex, name, 1, text)
#define QDIO_DBF_TEXT2(ex, name, text) QDIO_DBF_TEXT(ex, name, 2, text)

#ifdef CONFIG_QDIO_DEBUG
#define QDIO_DBF_TEXT3(ex, name, text) QDIO_DBF_TEXT(ex, name, 3, text)
#define QDIO_DBF_TEXT4(ex, name, text) QDIO_DBF_TEXT(ex, name, 4, text)
#define QDIO_DBF_TEXT5(ex, name, text) QDIO_DBF_TEXT(ex, name, 5, text)
#define QDIO_DBF_TEXT6(ex, name, text) QDIO_DBF_TEXT(ex, name, 6, text)
#else
#define QDIO_DBF_TEXT3(ex, name, text) do {} while (0)
#define QDIO_DBF_TEXT4(ex, name, text) do {} while (0)
#define QDIO_DBF_TEXT5(ex, name, text) do {} while (0)
#define QDIO_DBF_TEXT6(ex, name, text) do {} while (0)
#endif /* CONFIG_QDIO_DEBUG */


/* s390dbf views */
#define DBF_ERROR_HEX(addr, len) \
#define QDIO_DBF_SETUP_LEN		8
	do { \
#define QDIO_DBF_SETUP_PAGES		8
		debug_event(qdio_dbf_error, DBF_ERR, (void*)(addr), len); \
#define QDIO_DBF_SETUP_NR_AREAS		1
	} while (0)


#define QDIO_DBF_TRACE_LEN		8
#define QDIO_DBF_TRACE_NR_AREAS		2


#ifdef CONFIG_QDIO_DEBUG
#define DBF_DEV_EVENT(level, device, text...) \
#define QDIO_DBF_TRACE_PAGES		32
	do { \
#define QDIO_DBF_SETUP_LEVEL		6
		char debug_buffer[QDIO_DBF_LEN]; \
#define QDIO_DBF_TRACE_LEVEL		4
		if (qdio_dbf_passes(device->debug_area, level)) { \
#else /* !CONFIG_QDIO_DEBUG */
			snprintf(debug_buffer, QDIO_DBF_LEN, text); \
#define QDIO_DBF_TRACE_PAGES		8
			debug_text_event(device->debug_area, level, debug_buffer); \
#define QDIO_DBF_SETUP_LEVEL		2
		} \
#define QDIO_DBF_TRACE_LEVEL		2
	} while (0)
#endif /* CONFIG_QDIO_DEBUG */


extern debug_info_t *qdio_dbf_setup;
#define DBF_DEV_HEX(level, device, addr, len) \
extern debug_info_t *qdio_dbf_trace;
	do { \
		debug_event(device->debug_area, level, (void*)(addr), len); \
	} while (0)


void qdio_allocate_do_dbf(struct qdio_initialize *init_data);
void qdio_allocate_dbf(struct qdio_initialize *init_data,
void debug_print_bstat(struct qdio_q *q);
		       struct qdio_irq *irq_ptr);
void qdio_setup_debug_entries(struct qdio_irq *irq_ptr,
void qdio_setup_debug_entries(struct qdio_irq *irq_ptr,
			      struct ccw_device *cdev);
			      struct ccw_device *cdev);
void qdio_shutdown_debug_entries(struct qdio_irq *irq_ptr,
void qdio_shutdown_debug_entries(struct qdio_irq *irq_ptr,
				 struct ccw_device *cdev);
				 struct ccw_device *cdev);
int qdio_debug_init(void);
int qdio_debug_init(void);
void qdio_debug_exit(void);
void qdio_debug_exit(void);

#endif
#endif
Loading