diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-02-27 16:20:17 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-02-27 16:20:17 -0800 |
commit | 7981164791d18d5ed1dcdfa9598949ed158a5333 (patch) | |
tree | 6565e7406dd55eb5014efd3e54109159a47cb10e /drivers/s390/cio/qdio.h | |
parent | f1dd6ad599732fc89f36fdd65a2c2cf3c63a8711 (diff) | |
parent | a8d6356cdabf4495aaae7d3e89eb058b1909761c (diff) |
Merge branch 'for-linus' of git://git390.marist.edu/pub/scm/linux-2.6
* 'for-linus' of git://git390.marist.edu/pub/scm/linux-2.6: (35 commits)
[S390] time: remove unused code
[S390] zcore: Add prefix registers to dump header
[S390] correct vdso version string
[S390] add support for compressed kernels
[S390] Define new s390 ELF note sections in elf.h
[S390] codepage conversion of kernel parameter line
[S390] seq_file: convert drivers/s390/
[S390] add z9-ec/z10 instruction to kernel disassembler
[S390] dasd: correct offline processing
[S390] dasd: fix refcounting.
[S390] dasd: fix online/offline race
[S390] use kprobes_built_in() in mm/fault code
[S390] bug: use relative pointers in bug table entries
[S390] Cleanup struct _lowcore usage and defines.
[S390] free_initmem: reduce code duplication
[S390] Replace ENOTSUPP usage with EOPNOTSUPP
[S390] spinlock: check virtual cpu running status
[S390] sysinfo: fix SYSIB 3,2,2 structure
[S390] add MACHINE_IS_LPAR flag
[S390] qdio: optimize cache line usage of struct qdio_irq
...
Diffstat (limited to 'drivers/s390/cio/qdio.h')
-rw-r--r-- | drivers/s390/cio/qdio.h | 92 |
1 files changed, 56 insertions, 36 deletions
diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h index 44f2f6a97f3..48aa0647432 100644 --- a/drivers/s390/cio/qdio.h +++ b/drivers/s390/cio/qdio.h @@ -208,18 +208,27 @@ struct qdio_dev_perf_stat { unsigned int eqbs_partial; unsigned int sqbs; unsigned int sqbs_partial; +} ____cacheline_aligned; + +struct qdio_queue_perf_stat { + /* + * Sorted into order-2 buckets: 1, 2-3, 4-7, ... 64-127, 128. + * Since max. 127 SBALs are scanned reuse entry for 128 as queue full + * aka 127 SBALs found. + */ + unsigned int nr_sbals[8]; + unsigned int nr_sbal_error; + unsigned int nr_sbal_nop; + unsigned int nr_sbal_total; }; struct qdio_input_q { /* input buffer acknowledgement flag */ int polling; - /* first ACK'ed buffer */ int ack_start; - /* how much sbals are acknowledged with qebsm */ int ack_count; - /* last time of noticing incoming data */ u64 timestamp; }; @@ -227,40 +236,27 @@ struct qdio_input_q { struct qdio_output_q { /* PCIs are enabled for the queue */ int pci_out_enabled; - /* IQDIO: output multiple buffers (enhanced SIGA) */ int use_enh_siga; - /* timer to check for more outbound work */ struct timer_list timer; }; +/* + * Note on cache alignment: grouped slsb and write mostly data at the beginning + * sbal[] is read-only and starts on a new cacheline followed by read mostly. + */ struct qdio_q { struct slsb slsb; + union { struct qdio_input_q in; struct qdio_output_q out; } u; - /* queue number */ - int nr; - - /* bitmask of queue number */ - int mask; - - /* input or output queue */ - int is_input_q; - - /* list of thinint input queues */ - struct list_head entry; - - /* upper-layer program handler */ - qdio_handler_t (*handler); - /* * inbound: next buffer the program should check for - * outbound: next buffer to check for having been processed - * by the card + * outbound: next buffer to check if adapter processed it */ int first_to_check; @@ -273,16 +269,32 @@ struct qdio_q { /* number of buffers in use by the adapter */ atomic_t nr_buf_used; - struct qdio_irq *irq_ptr; - struct dentry *debugfs_q; - struct tasklet_struct tasklet; - /* error condition during a data transfer */ unsigned int qdio_error; - struct sl *sl; - struct qdio_buffer *sbal[QDIO_MAX_BUFFERS_PER_Q]; + struct tasklet_struct tasklet; + struct qdio_queue_perf_stat q_stats; + + struct qdio_buffer *sbal[QDIO_MAX_BUFFERS_PER_Q] ____cacheline_aligned; + + /* queue number */ + int nr; + + /* bitmask of queue number */ + int mask; + + /* input or output queue */ + int is_input_q; + + /* list of thinint input queues */ + struct list_head entry; + /* upper-layer program handler */ + qdio_handler_t (*handler); + + struct dentry *debugfs_q; + struct qdio_irq *irq_ptr; + struct sl *sl; /* * Warning: Leave this member at the end so it won't be cleared in * qdio_fill_qs. A page is allocated under this pointer and used for @@ -317,12 +329,8 @@ struct qdio_irq { struct qdio_ssqd_desc ssqd_desc; void (*orig_handler) (struct ccw_device *, unsigned long, struct irb *); - struct qdio_dev_perf_stat perf_stat; int perf_stat_enabled; - /* - * Warning: Leave these members together at the end so they won't be - * cleared in qdio_setup_irq. - */ + struct qdr *qdr; unsigned long chsc_page; @@ -331,6 +339,7 @@ struct qdio_irq { debug_info_t *debug_area; struct mutex setup_mutex; + struct qdio_dev_perf_stat perf_stat; }; /* helper functions */ @@ -341,9 +350,20 @@ struct qdio_irq { (irq->qib.qfmt == QDIO_IQDIO_QFMT || \ css_general_characteristics.aif_osa) -#define qperf(qdev,attr) qdev->perf_stat.attr -#define qperf_inc(q,attr) if (q->irq_ptr->perf_stat_enabled) \ - q->irq_ptr->perf_stat.attr++ +#define qperf(__qdev, __attr) ((__qdev)->perf_stat.(__attr)) + +#define qperf_inc(__q, __attr) \ +({ \ + struct qdio_irq *qdev = (__q)->irq_ptr; \ + if (qdev->perf_stat_enabled) \ + (qdev->perf_stat.__attr)++; \ +}) + +static inline void account_sbals_error(struct qdio_q *q, int count) +{ + q->q_stats.nr_sbal_error += count; + q->q_stats.nr_sbal_total += count; +} /* the highest iqdio queue is used for multicast */ static inline int multicast_outbound(struct qdio_q *q) |