Commit 09d2d38a authored by Frank Pavlic's avatar Frank Pavlic Committed by Jeff Garzik

[PATCH] s390: qeth driver fixes [4/6]

[PATCH 7/9] s390: qeth driver fixes [4/6]

From: Frank Pavlic <fpavlic@de.ibm.com>
	- fix kernel crash due to race,
	  set card->state to SOFTSETUP after
	  card and card->dev are initialized properly.
	- remove CONFIG_QETH_PERF_STATS, use sysfs attribute instead,
	  as we want to have the ability to turn on/off the
	  statistics at runtime.
Signed-off-by: default avatarFrank Pavlic <fpavlic@de.ibm.com>
Signed-off-by: default avatarJeff Garzik <jeff@garzik.org>
parent f7b65d70
...@@ -92,15 +92,6 @@ config QETH_VLAN ...@@ -92,15 +92,6 @@ config QETH_VLAN
If CONFIG_QETH is switched on, this option will include IEEE If CONFIG_QETH is switched on, this option will include IEEE
802.1q VLAN support in the qeth device driver. 802.1q VLAN support in the qeth device driver.
config QETH_PERF_STATS
bool "Performance statistics in /proc"
depends on QETH
help
When switched on, this option will add a file in the proc-fs
(/proc/qeth_perf_stats) containing performance statistics. It
may slightly impact performance, so this is only recommended for
internal tuning of the device driver.
config CCWGROUP config CCWGROUP
tristate tristate
default (LCS || CTC || QETH) default (LCS || CTC || QETH)
......
...@@ -176,7 +176,6 @@ extern struct ccwgroup_driver qeth_ccwgroup_driver; ...@@ -176,7 +176,6 @@ extern struct ccwgroup_driver qeth_ccwgroup_driver;
/** /**
* card stuff * card stuff
*/ */
#ifdef CONFIG_QETH_PERF_STATS
struct qeth_perf_stats { struct qeth_perf_stats {
unsigned int bufs_rec; unsigned int bufs_rec;
unsigned int bufs_sent; unsigned int bufs_sent;
...@@ -211,8 +210,10 @@ struct qeth_perf_stats { ...@@ -211,8 +210,10 @@ struct qeth_perf_stats {
unsigned int large_send_cnt; unsigned int large_send_cnt;
unsigned int sg_skbs_sent; unsigned int sg_skbs_sent;
unsigned int sg_frags_sent; unsigned int sg_frags_sent;
/* initial values when measuring starts */
unsigned long initial_rx_packets;
unsigned long initial_tx_packets;
}; };
#endif /* CONFIG_QETH_PERF_STATS */
/* Routing stuff */ /* Routing stuff */
struct qeth_routing_info { struct qeth_routing_info {
...@@ -767,6 +768,7 @@ struct qeth_card_options { ...@@ -767,6 +768,7 @@ struct qeth_card_options {
int fake_ll; int fake_ll;
int layer2; int layer2;
enum qeth_large_send_types large_send; enum qeth_large_send_types large_send;
int performance_stats;
}; };
/* /*
...@@ -819,9 +821,7 @@ struct qeth_card { ...@@ -819,9 +821,7 @@ struct qeth_card {
struct list_head cmd_waiter_list; struct list_head cmd_waiter_list;
/* QDIO buffer handling */ /* QDIO buffer handling */
struct qeth_qdio_info qdio; struct qeth_qdio_info qdio;
#ifdef CONFIG_QETH_PERF_STATS
struct qeth_perf_stats perf_stats; struct qeth_perf_stats perf_stats;
#endif /* CONFIG_QETH_PERF_STATS */
int use_hard_stop; int use_hard_stop;
int (*orig_hard_header)(struct sk_buff *,struct net_device *, int (*orig_hard_header)(struct sk_buff *,struct net_device *,
unsigned short,void *,void *,unsigned); unsigned short,void *,void *,unsigned);
...@@ -1049,13 +1049,11 @@ qeth_get_arphdr_type(int cardtype, int linktype) ...@@ -1049,13 +1049,11 @@ qeth_get_arphdr_type(int cardtype, int linktype)
} }
} }
#ifdef CONFIG_QETH_PERF_STATS
static inline int static inline int
qeth_get_micros(void) qeth_get_micros(void)
{ {
return (int) (get_clock() >> 12); return (int) (get_clock() >> 12);
} }
#endif
static inline int static inline int
qeth_get_qdio_q_format(struct qeth_card *card) qeth_get_qdio_q_format(struct qeth_card *card)
......
...@@ -179,9 +179,8 @@ qeth_eddp_fill_buffer(struct qeth_qdio_out_q *queue, ...@@ -179,9 +179,8 @@ qeth_eddp_fill_buffer(struct qeth_qdio_out_q *queue,
flush_cnt++; flush_cnt++;
} }
} else { } else {
#ifdef CONFIG_QETH_PERF_STATS if (queue->card->options.performance_stats)
queue->card->perf_stats.skbs_sent_pack++; queue->card->perf_stats.skbs_sent_pack++;
#endif
QETH_DBF_TEXT(trace, 6, "fillbfpa"); QETH_DBF_TEXT(trace, 6, "fillbfpa");
if (buf->next_element_to_fill >= if (buf->next_element_to_fill >=
QETH_MAX_BUFFER_ELEMENTS(queue->card)) { QETH_MAX_BUFFER_ELEMENTS(queue->card)) {
......
This diff is collapsed.
...@@ -173,7 +173,6 @@ static struct file_operations qeth_procfile_fops = { ...@@ -173,7 +173,6 @@ static struct file_operations qeth_procfile_fops = {
#define QETH_PERF_PROCFILE_NAME "qeth_perf" #define QETH_PERF_PROCFILE_NAME "qeth_perf"
static struct proc_dir_entry *qeth_perf_procfile; static struct proc_dir_entry *qeth_perf_procfile;
#ifdef CONFIG_QETH_PERF_STATS
static int static int
qeth_perf_procfile_seq_show(struct seq_file *s, void *it) qeth_perf_procfile_seq_show(struct seq_file *s, void *it)
{ {
...@@ -192,14 +191,21 @@ qeth_perf_procfile_seq_show(struct seq_file *s, void *it) ...@@ -192,14 +191,21 @@ qeth_perf_procfile_seq_show(struct seq_file *s, void *it)
CARD_DDEV_ID(card), CARD_DDEV_ID(card),
QETH_CARD_IFNAME(card) QETH_CARD_IFNAME(card)
); );
if (!card->options.performance_stats)
seq_printf(s, "Performance statistics are deactivated.\n");
seq_printf(s, " Skb's/buffers received : %lu/%u\n" seq_printf(s, " Skb's/buffers received : %lu/%u\n"
" Skb's/buffers sent : %lu/%u\n\n", " Skb's/buffers sent : %lu/%u\n\n",
card->stats.rx_packets, card->perf_stats.bufs_rec, card->stats.rx_packets -
card->stats.tx_packets, card->perf_stats.bufs_sent card->perf_stats.initial_rx_packets,
card->perf_stats.bufs_rec,
card->stats.tx_packets -
card->perf_stats.initial_tx_packets,
card->perf_stats.bufs_sent
); );
seq_printf(s, " Skb's/buffers sent without packing : %lu/%u\n" seq_printf(s, " Skb's/buffers sent without packing : %lu/%u\n"
" Skb's/buffers sent with packing : %u/%u\n\n", " Skb's/buffers sent with packing : %u/%u\n\n",
card->stats.tx_packets - card->perf_stats.skbs_sent_pack, card->stats.tx_packets - card->perf_stats.initial_tx_packets
- card->perf_stats.skbs_sent_pack,
card->perf_stats.bufs_sent - card->perf_stats.bufs_sent_pack, card->perf_stats.bufs_sent - card->perf_stats.bufs_sent_pack,
card->perf_stats.skbs_sent_pack, card->perf_stats.skbs_sent_pack,
card->perf_stats.bufs_sent_pack card->perf_stats.bufs_sent_pack
...@@ -275,11 +281,6 @@ static struct file_operations qeth_perf_procfile_fops = { ...@@ -275,11 +281,6 @@ static struct file_operations qeth_perf_procfile_fops = {
.release = seq_release, .release = seq_release,
}; };
#define qeth_perf_procfile_created qeth_perf_procfile
#else
#define qeth_perf_procfile_created 1
#endif /* CONFIG_QETH_PERF_STATS */
int __init int __init
qeth_create_procfs_entries(void) qeth_create_procfs_entries(void)
{ {
...@@ -288,15 +289,13 @@ qeth_create_procfs_entries(void) ...@@ -288,15 +289,13 @@ qeth_create_procfs_entries(void)
if (qeth_procfile) if (qeth_procfile)
qeth_procfile->proc_fops = &qeth_procfile_fops; qeth_procfile->proc_fops = &qeth_procfile_fops;
#ifdef CONFIG_QETH_PERF_STATS
qeth_perf_procfile = create_proc_entry(QETH_PERF_PROCFILE_NAME, qeth_perf_procfile = create_proc_entry(QETH_PERF_PROCFILE_NAME,
S_IFREG | 0444, NULL); S_IFREG | 0444, NULL);
if (qeth_perf_procfile) if (qeth_perf_procfile)
qeth_perf_procfile->proc_fops = &qeth_perf_procfile_fops; qeth_perf_procfile->proc_fops = &qeth_perf_procfile_fops;
#endif /* CONFIG_QETH_PERF_STATS */
if (qeth_procfile && if (qeth_procfile &&
qeth_perf_procfile_created) qeth_perf_procfile)
return 0; return 0;
else else
return -ENOMEM; return -ENOMEM;
......
...@@ -742,6 +742,47 @@ qeth_dev_layer2_store(struct device *dev, struct device_attribute *attr, const c ...@@ -742,6 +742,47 @@ qeth_dev_layer2_store(struct device *dev, struct device_attribute *attr, const c
static DEVICE_ATTR(layer2, 0644, qeth_dev_layer2_show, static DEVICE_ATTR(layer2, 0644, qeth_dev_layer2_show,
qeth_dev_layer2_store); qeth_dev_layer2_store);
static ssize_t
qeth_dev_performance_stats_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct qeth_card *card = dev->driver_data;
if (!card)
return -EINVAL;
return sprintf(buf, "%i\n", card->options.performance_stats ? 1:0);
}
static ssize_t
qeth_dev_performance_stats_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct qeth_card *card = dev->driver_data;
char *tmp;
int i;
if (!card)
return -EINVAL;
i = simple_strtoul(buf, &tmp, 16);
if ((i == 0) || (i == 1)) {
if (i == card->options.performance_stats)
return count;
card->options.performance_stats = i;
if (i == 0)
memset(&card->perf_stats, 0,
sizeof(struct qeth_perf_stats));
card->perf_stats.initial_rx_packets = card->stats.rx_packets;
card->perf_stats.initial_tx_packets = card->stats.tx_packets;
} else {
PRINT_WARN("performance_stats: write 0 or 1 to this file!\n");
return -EINVAL;
}
return count;
}
static DEVICE_ATTR(performance_stats, 0644, qeth_dev_performance_stats_show,
qeth_dev_performance_stats_store);
static ssize_t static ssize_t
qeth_dev_large_send_show(struct device *dev, struct device_attribute *attr, char *buf) qeth_dev_large_send_show(struct device *dev, struct device_attribute *attr, char *buf)
{ {
...@@ -928,6 +969,7 @@ static struct device_attribute * qeth_device_attrs[] = { ...@@ -928,6 +969,7 @@ static struct device_attribute * qeth_device_attrs[] = {
&dev_attr_canonical_macaddr, &dev_attr_canonical_macaddr,
&dev_attr_layer2, &dev_attr_layer2,
&dev_attr_large_send, &dev_attr_large_send,
&dev_attr_performance_stats,
NULL, NULL,
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment