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:
[S390] Update default configuration.
[S390] Have param.h simply include <asm-generic/param.h>.
[S390] qdio: convert global statistics to per-device stats

+254 -302
+75 -11
arch/s390/defconfig
··· 1 # 2 # Automatically generated make config: don't edit 3 - # Linux kernel version: 2.6.31 4 - # Tue Sep 22 17:43:13 2009 5 # 6 CONFIG_SCHED_MC=y 7 CONFIG_MMU=y ··· 51 # 52 CONFIG_TREE_RCU=y 53 # CONFIG_TREE_PREEMPT_RCU is not set 54 # CONFIG_RCU_TRACE is not set 55 CONFIG_RCU_FANOUT=64 56 # CONFIG_RCU_FANOUT_EXACT is not set ··· 114 # CONFIG_PERF_EVENTS is not set 115 # CONFIG_PERF_COUNTERS is not set 116 CONFIG_VM_EVENT_COUNTERS=y 117 - # CONFIG_STRIP_ASM_SYMS is not set 118 # CONFIG_COMPAT_BRK is not set 119 CONFIG_SLAB=y 120 # CONFIG_SLUB is not set ··· 149 CONFIG_BLOCK=y 150 CONFIG_BLK_DEV_BSG=y 151 # CONFIG_BLK_DEV_INTEGRITY is not set 152 CONFIG_BLOCK_COMPAT=y 153 154 # 155 # IO Schedulers 156 # 157 CONFIG_IOSCHED_NOOP=y 158 - CONFIG_IOSCHED_AS=y 159 CONFIG_IOSCHED_DEADLINE=y 160 CONFIG_IOSCHED_CFQ=y 161 - # CONFIG_DEFAULT_AS is not set 162 CONFIG_DEFAULT_DEADLINE=y 163 # CONFIG_DEFAULT_CFQ is not set 164 # CONFIG_DEFAULT_NOOP is not set 165 CONFIG_DEFAULT_IOSCHED="deadline" 166 CONFIG_PREEMPT_NOTIFIERS=y 167 CONFIG_FREEZER=y 168 169 # ··· 284 CONFIG_MEMORY_HOTPLUG_SPARSE=y 285 CONFIG_MEMORY_HOTREMOVE=y 286 CONFIG_PAGEFLAGS_EXTENDED=y 287 - CONFIG_SPLIT_PTLOCK_CPUS=4 288 CONFIG_MIGRATION=y 289 CONFIG_PHYS_ADDR_T_64BIT=y 290 CONFIG_ZONE_DMA_FLAG=1 291 CONFIG_BOUNCE=y 292 CONFIG_VIRT_TO_BUS=y 293 - CONFIG_HAVE_MLOCK=y 294 - CONFIG_HAVE_MLOCKED_PAGE_BIT=y 295 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 296 297 # ··· 395 CONFIG_INET6_XFRM_MODE_BEET=y 396 # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set 397 CONFIG_IPV6_SIT=y 398 CONFIG_IPV6_NDISC_NODETYPE=y 399 # CONFIG_IPV6_TUNNEL is not set 400 # CONFIG_IPV6_MULTIPLE_TABLES is not set ··· 561 # CONFIG_BLK_DEV_COW_COMMON is not set 562 CONFIG_BLK_DEV_LOOP=m 563 # CONFIG_BLK_DEV_CRYPTOLOOP is not set 564 CONFIG_BLK_DEV_NBD=m 565 # CONFIG_BLK_DEV_OSD is not set 566 CONFIG_BLK_DEV_RAM=y ··· 771 # CONFIG_PPS is not set 772 # CONFIG_POWER_SUPPLY is not set 773 # CONFIG_THERMAL is not set 774 - # CONFIG_THERMAL_HWMON is not set 775 # CONFIG_WATCHDOG is not set 776 # CONFIG_REGULATOR is not set 777 # CONFIG_MEMSTICK is not set ··· 924 CONFIG_ENABLE_MUST_CHECK=y 925 CONFIG_FRAME_WARN=2048 926 CONFIG_MAGIC_SYSRQ=y 927 # CONFIG_UNUSED_SYMBOLS is not set 928 CONFIG_DEBUG_FS=y 929 # CONFIG_HEADERS_CHECK is not set ··· 992 CONFIG_SAMPLES=y 993 # CONFIG_SAMPLE_KOBJECT is not set 994 # CONFIG_SAMPLE_KPROBES is not set 995 - # CONFIG_KMEMCHECK is not set 996 997 # 998 # Security options ··· 999 # CONFIG_KEYS is not set 1000 # CONFIG_SECURITY is not set 1001 # CONFIG_SECURITYFS is not set 1002 - # CONFIG_SECURITY_FILE_CAPABILITIES is not set 1003 CONFIG_CRYPTO=y 1004 1005 #
··· 1 # 2 # Automatically generated make config: don't edit 3 + # Linux kernel version: 2.6.33-rc2 4 + # Mon Jan 4 09:03:07 2010 5 # 6 CONFIG_SCHED_MC=y 7 CONFIG_MMU=y ··· 51 # 52 CONFIG_TREE_RCU=y 53 # CONFIG_TREE_PREEMPT_RCU is not set 54 + # CONFIG_TINY_RCU is not set 55 # CONFIG_RCU_TRACE is not set 56 CONFIG_RCU_FANOUT=64 57 # CONFIG_RCU_FANOUT_EXACT is not set ··· 113 # CONFIG_PERF_EVENTS is not set 114 # CONFIG_PERF_COUNTERS is not set 115 CONFIG_VM_EVENT_COUNTERS=y 116 # CONFIG_COMPAT_BRK is not set 117 CONFIG_SLAB=y 118 # CONFIG_SLUB is not set ··· 149 CONFIG_BLOCK=y 150 CONFIG_BLK_DEV_BSG=y 151 # CONFIG_BLK_DEV_INTEGRITY is not set 152 + # CONFIG_BLK_CGROUP is not set 153 CONFIG_BLOCK_COMPAT=y 154 155 # 156 # IO Schedulers 157 # 158 CONFIG_IOSCHED_NOOP=y 159 CONFIG_IOSCHED_DEADLINE=y 160 CONFIG_IOSCHED_CFQ=y 161 + # CONFIG_CFQ_GROUP_IOSCHED is not set 162 CONFIG_DEFAULT_DEADLINE=y 163 # CONFIG_DEFAULT_CFQ is not set 164 # CONFIG_DEFAULT_NOOP is not set 165 CONFIG_DEFAULT_IOSCHED="deadline" 166 CONFIG_PREEMPT_NOTIFIERS=y 167 + CONFIG_ARCH_INLINE_SPIN_TRYLOCK=y 168 + CONFIG_ARCH_INLINE_SPIN_TRYLOCK_BH=y 169 + CONFIG_ARCH_INLINE_SPIN_LOCK=y 170 + CONFIG_ARCH_INLINE_SPIN_LOCK_BH=y 171 + CONFIG_ARCH_INLINE_SPIN_LOCK_IRQ=y 172 + CONFIG_ARCH_INLINE_SPIN_LOCK_IRQSAVE=y 173 + CONFIG_ARCH_INLINE_SPIN_UNLOCK=y 174 + CONFIG_ARCH_INLINE_SPIN_UNLOCK_BH=y 175 + CONFIG_ARCH_INLINE_SPIN_UNLOCK_IRQ=y 176 + CONFIG_ARCH_INLINE_SPIN_UNLOCK_IRQRESTORE=y 177 + CONFIG_ARCH_INLINE_READ_TRYLOCK=y 178 + CONFIG_ARCH_INLINE_READ_LOCK=y 179 + CONFIG_ARCH_INLINE_READ_LOCK_BH=y 180 + CONFIG_ARCH_INLINE_READ_LOCK_IRQ=y 181 + CONFIG_ARCH_INLINE_READ_LOCK_IRQSAVE=y 182 + CONFIG_ARCH_INLINE_READ_UNLOCK=y 183 + CONFIG_ARCH_INLINE_READ_UNLOCK_BH=y 184 + CONFIG_ARCH_INLINE_READ_UNLOCK_IRQ=y 185 + CONFIG_ARCH_INLINE_READ_UNLOCK_IRQRESTORE=y 186 + CONFIG_ARCH_INLINE_WRITE_TRYLOCK=y 187 + CONFIG_ARCH_INLINE_WRITE_LOCK=y 188 + CONFIG_ARCH_INLINE_WRITE_LOCK_BH=y 189 + CONFIG_ARCH_INLINE_WRITE_LOCK_IRQ=y 190 + CONFIG_ARCH_INLINE_WRITE_LOCK_IRQSAVE=y 191 + CONFIG_ARCH_INLINE_WRITE_UNLOCK=y 192 + CONFIG_ARCH_INLINE_WRITE_UNLOCK_BH=y 193 + CONFIG_ARCH_INLINE_WRITE_UNLOCK_IRQ=y 194 + CONFIG_ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE=y 195 + # CONFIG_INLINE_SPIN_TRYLOCK is not set 196 + # CONFIG_INLINE_SPIN_TRYLOCK_BH is not set 197 + # CONFIG_INLINE_SPIN_LOCK is not set 198 + # CONFIG_INLINE_SPIN_LOCK_BH is not set 199 + # CONFIG_INLINE_SPIN_LOCK_IRQ is not set 200 + # CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set 201 + # CONFIG_INLINE_SPIN_UNLOCK is not set 202 + # CONFIG_INLINE_SPIN_UNLOCK_BH is not set 203 + # CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set 204 + # CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set 205 + # CONFIG_INLINE_READ_TRYLOCK is not set 206 + # CONFIG_INLINE_READ_LOCK is not set 207 + # CONFIG_INLINE_READ_LOCK_BH is not set 208 + # CONFIG_INLINE_READ_LOCK_IRQ is not set 209 + # CONFIG_INLINE_READ_LOCK_IRQSAVE is not set 210 + # CONFIG_INLINE_READ_UNLOCK is not set 211 + # CONFIG_INLINE_READ_UNLOCK_BH is not set 212 + # CONFIG_INLINE_READ_UNLOCK_IRQ is not set 213 + # CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set 214 + # CONFIG_INLINE_WRITE_TRYLOCK is not set 215 + # CONFIG_INLINE_WRITE_LOCK is not set 216 + # CONFIG_INLINE_WRITE_LOCK_BH is not set 217 + # CONFIG_INLINE_WRITE_LOCK_IRQ is not set 218 + # CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set 219 + # CONFIG_INLINE_WRITE_UNLOCK is not set 220 + # CONFIG_INLINE_WRITE_UNLOCK_BH is not set 221 + # CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set 222 + # CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set 223 + # CONFIG_MUTEX_SPIN_ON_OWNER is not set 224 CONFIG_FREEZER=y 225 226 # ··· 227 CONFIG_MEMORY_HOTPLUG_SPARSE=y 228 CONFIG_MEMORY_HOTREMOVE=y 229 CONFIG_PAGEFLAGS_EXTENDED=y 230 + CONFIG_SPLIT_PTLOCK_CPUS=999999 231 CONFIG_MIGRATION=y 232 CONFIG_PHYS_ADDR_T_64BIT=y 233 CONFIG_ZONE_DMA_FLAG=1 234 CONFIG_BOUNCE=y 235 CONFIG_VIRT_TO_BUS=y 236 + # CONFIG_KSM is not set 237 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 238 239 # ··· 339 CONFIG_INET6_XFRM_MODE_BEET=y 340 # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set 341 CONFIG_IPV6_SIT=y 342 + # CONFIG_IPV6_SIT_6RD is not set 343 CONFIG_IPV6_NDISC_NODETYPE=y 344 # CONFIG_IPV6_TUNNEL is not set 345 # CONFIG_IPV6_MULTIPLE_TABLES is not set ··· 504 # CONFIG_BLK_DEV_COW_COMMON is not set 505 CONFIG_BLK_DEV_LOOP=m 506 # CONFIG_BLK_DEV_CRYPTOLOOP is not set 507 + 508 + # 509 + # DRBD disabled because PROC_FS, INET or CONNECTOR not selected 510 + # 511 CONFIG_BLK_DEV_NBD=m 512 # CONFIG_BLK_DEV_OSD is not set 513 CONFIG_BLK_DEV_RAM=y ··· 710 # CONFIG_PPS is not set 711 # CONFIG_POWER_SUPPLY is not set 712 # CONFIG_THERMAL is not set 713 # CONFIG_WATCHDOG is not set 714 # CONFIG_REGULATOR is not set 715 # CONFIG_MEMSTICK is not set ··· 864 CONFIG_ENABLE_MUST_CHECK=y 865 CONFIG_FRAME_WARN=2048 866 CONFIG_MAGIC_SYSRQ=y 867 + # CONFIG_STRIP_ASM_SYMS is not set 868 # CONFIG_UNUSED_SYMBOLS is not set 869 CONFIG_DEBUG_FS=y 870 # CONFIG_HEADERS_CHECK is not set ··· 931 CONFIG_SAMPLES=y 932 # CONFIG_SAMPLE_KOBJECT is not set 933 # CONFIG_SAMPLE_KPROBES is not set 934 935 # 936 # Security options ··· 939 # CONFIG_KEYS is not set 940 # CONFIG_SECURITY is not set 941 # CONFIG_SECURITYFS is not set 942 + # CONFIG_DEFAULT_SECURITY_SELINUX is not set 943 + # CONFIG_DEFAULT_SECURITY_SMACK is not set 944 + # CONFIG_DEFAULT_SECURITY_TOMOYO is not set 945 + CONFIG_DEFAULT_SECURITY_DAC=y 946 + CONFIG_DEFAULT_SECURITY="" 947 CONFIG_CRYPTO=y 948 949 #
+2 -26
arch/s390/include/asm/param.h
··· 1 - /* 2 - * include/asm-s390/param.h 3 - * 4 - * S390 version 5 - * 6 - * Derived from "include/asm-i386/param.h" 7 - */ 8 - 9 #ifndef _ASMS390_PARAM_H 10 #define _ASMS390_PARAM_H 11 12 - #ifdef __KERNEL__ 13 - # define HZ CONFIG_HZ /* Internal kernel timer frequency */ 14 - # define USER_HZ 100 /* .. some user interfaces are in "ticks" */ 15 - # define CLOCKS_PER_SEC (USER_HZ) /* like times() */ 16 - #endif 17 18 - #ifndef HZ 19 - #define HZ 100 20 - #endif 21 - 22 - #define EXEC_PAGESIZE 4096 23 - 24 - #ifndef NOGROUP 25 - #define NOGROUP (-1) 26 - #endif 27 - 28 - #define MAXHOSTNAMELEN 64 /* max length of hostname */ 29 - 30 - #endif
··· 1 #ifndef _ASMS390_PARAM_H 2 #define _ASMS390_PARAM_H 3 4 + #include <asm-generic/param.h> 5 6 + #endif /* _ASMS390_PARAM_H */
+1 -1
drivers/s390/cio/Makefile
··· 10 obj-$(CONFIG_CHSC_SCH) += chsc_sch.o 11 obj-$(CONFIG_CCWGROUP) += ccwgroup.o 12 13 - qdio-objs := qdio_main.o qdio_thinint.o qdio_debug.o qdio_perf.o qdio_setup.o 14 obj-$(CONFIG_QDIO) += qdio.o
··· 10 obj-$(CONFIG_CHSC_SCH) += chsc_sch.o 11 obj-$(CONFIG_CCWGROUP) += ccwgroup.o 12 13 + qdio-objs := qdio_main.o qdio_thinint.o qdio_debug.o qdio_setup.o 14 obj-$(CONFIG_QDIO) += qdio.o
+35 -1
drivers/s390/cio/qdio.h
··· 182 u32:32; 183 } __attribute__ ((packed)); 184 185 struct qdio_input_q { 186 /* input buffer acknowledgement flag */ 187 int polling; ··· 297 u32 *dsci; /* address of device state change indicator */ 298 struct ccw_device *cdev; 299 struct dentry *debugfs_dev; 300 301 unsigned long int_parm; 302 struct subchannel_id schid; ··· 315 struct ciw aqueue; 316 317 struct qdio_ssqd_desc ssqd_desc; 318 - 319 void (*orig_handler) (struct ccw_device *, unsigned long, struct irb *); 320 321 /* 322 * Warning: Leave these members together at the end so they won't be 323 * cleared in qdio_setup_irq. ··· 340 #define is_thinint_irq(irq) \ 341 (irq->qib.qfmt == QDIO_IQDIO_QFMT || \ 342 css_general_characteristics.aif_osa) 343 344 /* the highest iqdio queue is used for multicast */ 345 static inline int multicast_outbound(struct qdio_q *q)
··· 182 u32:32; 183 } __attribute__ ((packed)); 184 185 + struct qdio_dev_perf_stat { 186 + unsigned int adapter_int; 187 + unsigned int qdio_int; 188 + unsigned int pci_request_int; 189 + 190 + unsigned int tasklet_inbound; 191 + unsigned int tasklet_inbound_resched; 192 + unsigned int tasklet_inbound_resched2; 193 + unsigned int tasklet_outbound; 194 + 195 + unsigned int siga_read; 196 + unsigned int siga_write; 197 + unsigned int siga_sync; 198 + 199 + unsigned int inbound_call; 200 + unsigned int inbound_handler; 201 + unsigned int stop_polling; 202 + unsigned int inbound_queue_full; 203 + unsigned int outbound_call; 204 + unsigned int outbound_handler; 205 + unsigned int fast_requeue; 206 + unsigned int target_full; 207 + unsigned int eqbs; 208 + unsigned int eqbs_partial; 209 + unsigned int sqbs; 210 + unsigned int sqbs_partial; 211 + }; 212 + 213 struct qdio_input_q { 214 /* input buffer acknowledgement flag */ 215 int polling; ··· 269 u32 *dsci; /* address of device state change indicator */ 270 struct ccw_device *cdev; 271 struct dentry *debugfs_dev; 272 + struct dentry *debugfs_perf; 273 274 unsigned long int_parm; 275 struct subchannel_id schid; ··· 286 struct ciw aqueue; 287 288 struct qdio_ssqd_desc ssqd_desc; 289 void (*orig_handler) (struct ccw_device *, unsigned long, struct irb *); 290 291 + struct qdio_dev_perf_stat perf_stat; 292 + int perf_stat_enabled; 293 /* 294 * Warning: Leave these members together at the end so they won't be 295 * cleared in qdio_setup_irq. ··· 310 #define is_thinint_irq(irq) \ 311 (irq->qib.qfmt == QDIO_IQDIO_QFMT || \ 312 css_general_characteristics.aif_osa) 313 + 314 + #define qperf(qdev,attr) qdev->perf_stat.attr 315 + #define qperf_inc(q,attr) if (q->irq_ptr->perf_stat_enabled) \ 316 + q->irq_ptr->perf_stat.attr++ 317 318 /* the highest iqdio queue is used for multicast */ 319 static inline int multicast_outbound(struct qdio_q *q)
+106 -8
drivers/s390/cio/qdio_debug.c
··· 55 if (!q) 56 return 0; 57 58 - seq_printf(m, "device state indicator: %d\n", *(u32 *)q->irq_ptr->dsci); 59 - seq_printf(m, "nr_used: %d\n", atomic_read(&q->nr_buf_used)); 60 - seq_printf(m, "ftc: %d\n", q->first_to_check); 61 - seq_printf(m, "last_move: %d\n", q->last_move); 62 - seq_printf(m, "polling: %d\n", q->u.in.polling); 63 - seq_printf(m, "ack start: %d\n", q->u.in.ack_start); 64 - seq_printf(m, "ack count: %d\n", q->u.in.ack_count); 65 seq_printf(m, "slsb buffer states:\n"); 66 seq_printf(m, "|0 |8 |16 |24 |32 |40 |48 |56 63|\n"); 67 ··· 108 109 if (!q) 110 return 0; 111 - 112 if (q->is_input_q) 113 xchg(q->irq_ptr->dsci, 1); 114 local_bh_disable(); ··· 131 .release = single_release, 132 }; 133 134 static void setup_debugfs_entry(struct qdio_q *q, struct ccw_device *cdev) 135 { 136 char name[QDIO_DEBUGFS_NAME_LEN]; ··· 245 debugfs_root); 246 if (IS_ERR(irq_ptr->debugfs_dev)) 247 irq_ptr->debugfs_dev = NULL; 248 for_each_input_queue(irq_ptr, q, i) 249 setup_debugfs_entry(q, cdev); 250 for_each_output_queue(irq_ptr, q, i) ··· 268 debugfs_remove(q->debugfs_q); 269 for_each_output_queue(irq_ptr, q, i) 270 debugfs_remove(q->debugfs_q); 271 debugfs_remove(irq_ptr->debugfs_dev); 272 } 273
··· 55 if (!q) 56 return 0; 57 58 + seq_printf(m, "DSCI: %d nr_used: %d\n", 59 + *(u32 *)q->irq_ptr->dsci, atomic_read(&q->nr_buf_used)); 60 + seq_printf(m, "ftc: %d last_move: %d\n", q->first_to_check, q->last_move); 61 + seq_printf(m, "polling: %d ack start: %d ack count: %d\n", 62 + q->u.in.polling, q->u.in.ack_start, q->u.in.ack_count); 63 seq_printf(m, "slsb buffer states:\n"); 64 seq_printf(m, "|0 |8 |16 |24 |32 |40 |48 |56 63|\n"); 65 ··· 110 111 if (!q) 112 return 0; 113 if (q->is_input_q) 114 xchg(q->irq_ptr->dsci, 1); 115 local_bh_disable(); ··· 134 .release = single_release, 135 }; 136 137 + static char *qperf_names[] = { 138 + "Assumed adapter interrupts", 139 + "QDIO interrupts", 140 + "Requested PCIs", 141 + "Inbound tasklet runs", 142 + "Inbound tasklet resched", 143 + "Inbound tasklet resched2", 144 + "Outbound tasklet runs", 145 + "SIGA read", 146 + "SIGA write", 147 + "SIGA sync", 148 + "Inbound calls", 149 + "Inbound handler", 150 + "Inbound stop_polling", 151 + "Inbound queue full", 152 + "Outbound calls", 153 + "Outbound handler", 154 + "Outbound fast_requeue", 155 + "Outbound target_full", 156 + "QEBSM eqbs", 157 + "QEBSM eqbs partial", 158 + "QEBSM sqbs", 159 + "QEBSM sqbs partial" 160 + }; 161 + 162 + static int qperf_show(struct seq_file *m, void *v) 163 + { 164 + struct qdio_irq *irq_ptr = m->private; 165 + unsigned int *stat; 166 + int i; 167 + 168 + if (!irq_ptr) 169 + return 0; 170 + if (!irq_ptr->perf_stat_enabled) { 171 + seq_printf(m, "disabled\n"); 172 + return 0; 173 + } 174 + stat = (unsigned int *)&irq_ptr->perf_stat; 175 + 176 + for (i = 0; i < ARRAY_SIZE(qperf_names); i++) 177 + seq_printf(m, "%26s:\t%u\n", 178 + qperf_names[i], *(stat + i)); 179 + return 0; 180 + } 181 + 182 + static ssize_t qperf_seq_write(struct file *file, const char __user *ubuf, 183 + size_t count, loff_t *off) 184 + { 185 + struct seq_file *seq = file->private_data; 186 + struct qdio_irq *irq_ptr = seq->private; 187 + unsigned long val; 188 + char buf[8]; 189 + int ret; 190 + 191 + if (!irq_ptr) 192 + return 0; 193 + if (count >= sizeof(buf)) 194 + return -EINVAL; 195 + if (copy_from_user(&buf, ubuf, count)) 196 + return -EFAULT; 197 + buf[count] = 0; 198 + 199 + ret = strict_strtoul(buf, 10, &val); 200 + if (ret < 0) 201 + return ret; 202 + 203 + switch (val) { 204 + case 0: 205 + irq_ptr->perf_stat_enabled = 0; 206 + memset(&irq_ptr->perf_stat, 0, sizeof(irq_ptr->perf_stat)); 207 + break; 208 + case 1: 209 + irq_ptr->perf_stat_enabled = 1; 210 + break; 211 + } 212 + return count; 213 + } 214 + 215 + static int qperf_seq_open(struct inode *inode, struct file *filp) 216 + { 217 + return single_open(filp, qperf_show, 218 + filp->f_path.dentry->d_inode->i_private); 219 + } 220 + 221 + static struct file_operations debugfs_perf_fops = { 222 + .owner = THIS_MODULE, 223 + .open = qperf_seq_open, 224 + .read = seq_read, 225 + .write = qperf_seq_write, 226 + .llseek = seq_lseek, 227 + .release = single_release, 228 + }; 229 static void setup_debugfs_entry(struct qdio_q *q, struct ccw_device *cdev) 230 { 231 char name[QDIO_DEBUGFS_NAME_LEN]; ··· 156 debugfs_root); 157 if (IS_ERR(irq_ptr->debugfs_dev)) 158 irq_ptr->debugfs_dev = NULL; 159 + 160 + irq_ptr->debugfs_perf = debugfs_create_file("statistics", 161 + S_IFREG | S_IRUGO | S_IWUSR, 162 + irq_ptr->debugfs_dev, irq_ptr, 163 + &debugfs_perf_fops); 164 + if (IS_ERR(irq_ptr->debugfs_perf)) 165 + irq_ptr->debugfs_perf = NULL; 166 + 167 for_each_input_queue(irq_ptr, q, i) 168 setup_debugfs_entry(q, cdev); 169 for_each_output_queue(irq_ptr, q, i) ··· 171 debugfs_remove(q->debugfs_q); 172 for_each_output_queue(irq_ptr, q, i) 173 debugfs_remove(q->debugfs_q); 174 + debugfs_remove(irq_ptr->debugfs_perf); 175 debugfs_remove(irq_ptr->debugfs_dev); 176 } 177
+33 -38
drivers/s390/cio/qdio_main.c
··· 22 #include "device.h" 23 #include "qdio.h" 24 #include "qdio_debug.h" 25 - #include "qdio_perf.h" 26 27 MODULE_AUTHOR("Utz Bacher <utz.bacher@de.ibm.com>,"\ 28 "Jan Glauber <jang@linux.vnet.ibm.com>"); ··· 125 int rc; 126 127 BUG_ON(!q->irq_ptr->sch_token); 128 - qdio_perf_stat_inc(&perf_stats.debug_eqbs_all); 129 130 if (!q->is_input_q) 131 nr += q->irq_ptr->nr_input_qs; ··· 138 * buffers later. 139 */ 140 if ((ccq == 96) && (count != tmp_count)) { 141 - qdio_perf_stat_inc(&perf_stats.debug_eqbs_incomplete); 142 return (count - tmp_count); 143 } 144 ··· 181 return 0; 182 183 BUG_ON(!q->irq_ptr->sch_token); 184 - qdio_perf_stat_inc(&perf_stats.debug_sqbs_all); 185 186 if (!q->is_input_q) 187 nr += q->irq_ptr->nr_input_qs; ··· 190 rc = qdio_check_ccq(q, ccq); 191 if (rc == 1) { 192 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "SQBS again:%2d", ccq); 193 - qdio_perf_stat_inc(&perf_stats.debug_sqbs_incomplete); 194 goto again; 195 } 196 if (rc < 0) { ··· 284 return 0; 285 286 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "siga-s:%1d", q->nr); 287 - qdio_perf_stat_inc(&perf_stats.siga_sync); 288 289 cc = do_siga_sync(q->irq_ptr->schid, output, input); 290 if (cc) ··· 349 int cc; 350 351 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "siga-r:%1d", q->nr); 352 - qdio_perf_stat_inc(&perf_stats.siga_in); 353 354 cc = do_siga_input(q->irq_ptr->schid, q->mask); 355 if (cc) ··· 381 return; 382 383 q->u.in.polling = 0; 384 - qdio_perf_stat_inc(&perf_stats.debug_stop_polling); 385 386 /* show the card that we are not polling anymore */ 387 if (is_qebsm(q)) { ··· 399 /* special handling for no target buffer empty */ 400 if ((!q->is_input_q && 401 (q->sbal[q->first_to_check]->element[15].flags & 0xff) == 0x10)) { 402 - qdio_perf_stat_inc(&perf_stats.outbound_target_full); 403 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "OUTFULL FTC:%02x", 404 q->first_to_check); 405 return; ··· 486 inbound_primed(q, count); 487 q->first_to_check = add_buf(q->first_to_check, count); 488 if (atomic_sub(count, &q->nr_buf_used) == 0) 489 - qdio_perf_stat_inc(&perf_stats.inbound_queue_full); 490 break; 491 case SLSB_P_INPUT_ERROR: 492 announce_buffer_error(q, count); ··· 566 count = sub_buf(end, start); 567 568 if (q->is_input_q) { 569 - qdio_perf_stat_inc(&perf_stats.inbound_handler); 570 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "kih s:%02x c:%02x", start, count); 571 } else 572 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "koh: s:%02x c:%02x", 573 start, count); 574 ··· 583 584 static void __qdio_inbound_processing(struct qdio_q *q) 585 { 586 - qdio_perf_stat_inc(&perf_stats.tasklet_inbound); 587 again: 588 if (!qdio_inbound_q_moved(q)) 589 return; 590 591 qdio_kick_handler(q); 592 593 - if (!qdio_inbound_q_done(q)) 594 /* means poll time is not yet over */ 595 goto again; 596 597 qdio_stop_polling(q); 598 /* 599 * We need to check again to not lose initiative after 600 * resetting the ACK state. 601 */ 602 - if (!qdio_inbound_q_done(q)) 603 goto again; 604 } 605 606 void qdio_inbound_processing(unsigned long data) ··· 692 return 0; 693 694 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "siga-w:%1d", q->nr); 695 - qdio_perf_stat_inc(&perf_stats.siga_out); 696 697 cc = qdio_siga_output(q, &busy_bit); 698 switch (cc) { ··· 715 716 static void __qdio_outbound_processing(struct qdio_q *q) 717 { 718 - qdio_perf_stat_inc(&perf_stats.tasklet_outbound); 719 BUG_ON(atomic_read(&q->nr_buf_used) < 0); 720 721 if (qdio_outbound_q_moved(q)) ··· 743 */ 744 if (qdio_outbound_q_done(q)) 745 del_timer(&q->u.out.timer); 746 - else { 747 - if (!timer_pending(&q->u.out.timer)) { 748 mod_timer(&q->u.out.timer, jiffies + 10 * HZ); 749 - qdio_perf_stat_inc(&perf_stats.debug_tl_out_timer); 750 - } 751 - } 752 return; 753 754 sched: ··· 785 786 static void __tiqdio_inbound_processing(struct qdio_q *q) 787 { 788 - qdio_perf_stat_inc(&perf_stats.thinint_inbound); 789 qdio_sync_after_thinint(q); 790 791 /* ··· 800 qdio_kick_handler(q); 801 802 if (!qdio_inbound_q_done(q)) { 803 - qdio_perf_stat_inc(&perf_stats.thinint_inbound_loop); 804 if (likely(q->irq_ptr->state != QDIO_IRQ_STATE_STOPPED)) { 805 tasklet_schedule(&q->tasklet); 806 return; ··· 813 * resetting the ACK state. 814 */ 815 if (!qdio_inbound_q_done(q)) { 816 - qdio_perf_stat_inc(&perf_stats.thinint_inbound_loop2); 817 if (likely(q->irq_ptr->state != QDIO_IRQ_STATE_STOPPED)) 818 tasklet_schedule(&q->tasklet); 819 } ··· 851 852 if (unlikely(irq_ptr->state == QDIO_IRQ_STATE_STOPPED)) 853 return; 854 - 855 - qdio_perf_stat_inc(&perf_stats.pci_int); 856 857 for_each_input_queue(irq_ptr, q, i) 858 tasklet_schedule(&q->tasklet); ··· 921 { 922 struct qdio_irq *irq_ptr = cdev->private->qdio_data; 923 int cstat, dstat; 924 - 925 - qdio_perf_stat_inc(&perf_stats.qdio_int); 926 927 if (!intparm || !irq_ptr) { 928 DBF_ERROR("qint:%4x", cdev->private->schid.sch_no); ··· 1380 { 1381 int used, diff; 1382 1383 if (!q->u.in.polling) 1384 goto set; 1385 ··· 1437 unsigned char state; 1438 int used, rc = 0; 1439 1440 - qdio_perf_stat_inc(&perf_stats.outbound_handler); 1441 1442 count = set_buf_states(q, bufnr, SLSB_CU_OUTPUT_PRIMED, count); 1443 used = atomic_add_return(count, &q->nr_buf_used); 1444 BUG_ON(used > QDIO_MAX_BUFFERS_PER_Q); 1445 1446 - if (callflags & QDIO_FLAG_PCI_OUT) 1447 q->u.out.pci_out_enabled = 1; 1448 else 1449 q->u.out.pci_out_enabled = 0; 1450 ··· 1485 if (state != SLSB_CU_OUTPUT_PRIMED) 1486 rc = qdio_kick_outbound_q(q); 1487 else 1488 - qdio_perf_stat_inc(&perf_stats.fast_requeue); 1489 1490 out: 1491 tasklet_schedule(&q->tasklet); ··· 1541 rc = qdio_debug_init(); 1542 if (rc) 1543 goto out_ti; 1544 - rc = qdio_setup_perf_stats(); 1545 - if (rc) 1546 - goto out_debug; 1547 rc = tiqdio_register_thinints(); 1548 if (rc) 1549 - goto out_perf; 1550 return 0; 1551 1552 - out_perf: 1553 - qdio_remove_perf_stats(); 1554 out_debug: 1555 qdio_debug_exit(); 1556 out_ti: ··· 1559 { 1560 tiqdio_unregister_thinints(); 1561 tiqdio_free_memory(); 1562 - qdio_remove_perf_stats(); 1563 qdio_debug_exit(); 1564 qdio_setup_exit(); 1565 }
··· 22 #include "device.h" 23 #include "qdio.h" 24 #include "qdio_debug.h" 25 26 MODULE_AUTHOR("Utz Bacher <utz.bacher@de.ibm.com>,"\ 27 "Jan Glauber <jang@linux.vnet.ibm.com>"); ··· 126 int rc; 127 128 BUG_ON(!q->irq_ptr->sch_token); 129 + qperf_inc(q, eqbs); 130 131 if (!q->is_input_q) 132 nr += q->irq_ptr->nr_input_qs; ··· 139 * buffers later. 140 */ 141 if ((ccq == 96) && (count != tmp_count)) { 142 + qperf_inc(q, eqbs_partial); 143 return (count - tmp_count); 144 } 145 ··· 182 return 0; 183 184 BUG_ON(!q->irq_ptr->sch_token); 185 + qperf_inc(q, sqbs); 186 187 if (!q->is_input_q) 188 nr += q->irq_ptr->nr_input_qs; ··· 191 rc = qdio_check_ccq(q, ccq); 192 if (rc == 1) { 193 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "SQBS again:%2d", ccq); 194 + qperf_inc(q, sqbs_partial); 195 goto again; 196 } 197 if (rc < 0) { ··· 285 return 0; 286 287 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "siga-s:%1d", q->nr); 288 + qperf_inc(q, siga_sync); 289 290 cc = do_siga_sync(q->irq_ptr->schid, output, input); 291 if (cc) ··· 350 int cc; 351 352 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "siga-r:%1d", q->nr); 353 + qperf_inc(q, siga_read); 354 355 cc = do_siga_input(q->irq_ptr->schid, q->mask); 356 if (cc) ··· 382 return; 383 384 q->u.in.polling = 0; 385 + qperf_inc(q, stop_polling); 386 387 /* show the card that we are not polling anymore */ 388 if (is_qebsm(q)) { ··· 400 /* special handling for no target buffer empty */ 401 if ((!q->is_input_q && 402 (q->sbal[q->first_to_check]->element[15].flags & 0xff) == 0x10)) { 403 + qperf_inc(q, target_full); 404 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "OUTFULL FTC:%02x", 405 q->first_to_check); 406 return; ··· 487 inbound_primed(q, count); 488 q->first_to_check = add_buf(q->first_to_check, count); 489 if (atomic_sub(count, &q->nr_buf_used) == 0) 490 + qperf_inc(q, inbound_queue_full); 491 break; 492 case SLSB_P_INPUT_ERROR: 493 announce_buffer_error(q, count); ··· 567 count = sub_buf(end, start); 568 569 if (q->is_input_q) { 570 + qperf_inc(q, inbound_handler); 571 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "kih s:%02x c:%02x", start, count); 572 } else 573 + qperf_inc(q, outbound_handler); 574 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "koh: s:%02x c:%02x", 575 start, count); 576 ··· 583 584 static void __qdio_inbound_processing(struct qdio_q *q) 585 { 586 + qperf_inc(q, tasklet_inbound); 587 again: 588 if (!qdio_inbound_q_moved(q)) 589 return; 590 591 qdio_kick_handler(q); 592 593 + if (!qdio_inbound_q_done(q)) { 594 /* means poll time is not yet over */ 595 + qperf_inc(q, tasklet_inbound_resched); 596 goto again; 597 + } 598 599 qdio_stop_polling(q); 600 /* 601 * We need to check again to not lose initiative after 602 * resetting the ACK state. 603 */ 604 + if (!qdio_inbound_q_done(q)) { 605 + qperf_inc(q, tasklet_inbound_resched2); 606 goto again; 607 + } 608 } 609 610 void qdio_inbound_processing(unsigned long data) ··· 688 return 0; 689 690 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "siga-w:%1d", q->nr); 691 + qperf_inc(q, siga_write); 692 693 cc = qdio_siga_output(q, &busy_bit); 694 switch (cc) { ··· 711 712 static void __qdio_outbound_processing(struct qdio_q *q) 713 { 714 + qperf_inc(q, tasklet_outbound); 715 BUG_ON(atomic_read(&q->nr_buf_used) < 0); 716 717 if (qdio_outbound_q_moved(q)) ··· 739 */ 740 if (qdio_outbound_q_done(q)) 741 del_timer(&q->u.out.timer); 742 + else 743 + if (!timer_pending(&q->u.out.timer)) 744 mod_timer(&q->u.out.timer, jiffies + 10 * HZ); 745 return; 746 747 sched: ··· 784 785 static void __tiqdio_inbound_processing(struct qdio_q *q) 786 { 787 + qperf_inc(q, tasklet_inbound); 788 qdio_sync_after_thinint(q); 789 790 /* ··· 799 qdio_kick_handler(q); 800 801 if (!qdio_inbound_q_done(q)) { 802 + qperf_inc(q, tasklet_inbound_resched); 803 if (likely(q->irq_ptr->state != QDIO_IRQ_STATE_STOPPED)) { 804 tasklet_schedule(&q->tasklet); 805 return; ··· 812 * resetting the ACK state. 813 */ 814 if (!qdio_inbound_q_done(q)) { 815 + qperf_inc(q, tasklet_inbound_resched2); 816 if (likely(q->irq_ptr->state != QDIO_IRQ_STATE_STOPPED)) 817 tasklet_schedule(&q->tasklet); 818 } ··· 850 851 if (unlikely(irq_ptr->state == QDIO_IRQ_STATE_STOPPED)) 852 return; 853 854 for_each_input_queue(irq_ptr, q, i) 855 tasklet_schedule(&q->tasklet); ··· 922 { 923 struct qdio_irq *irq_ptr = cdev->private->qdio_data; 924 int cstat, dstat; 925 926 if (!intparm || !irq_ptr) { 927 DBF_ERROR("qint:%4x", cdev->private->schid.sch_no); ··· 1383 { 1384 int used, diff; 1385 1386 + qperf_inc(q, inbound_call); 1387 + 1388 if (!q->u.in.polling) 1389 goto set; 1390 ··· 1438 unsigned char state; 1439 int used, rc = 0; 1440 1441 + qperf_inc(q, outbound_call); 1442 1443 count = set_buf_states(q, bufnr, SLSB_CU_OUTPUT_PRIMED, count); 1444 used = atomic_add_return(count, &q->nr_buf_used); 1445 BUG_ON(used > QDIO_MAX_BUFFERS_PER_Q); 1446 1447 + if (callflags & QDIO_FLAG_PCI_OUT) { 1448 q->u.out.pci_out_enabled = 1; 1449 + qperf_inc(q, pci_request_int); 1450 + } 1451 else 1452 q->u.out.pci_out_enabled = 0; 1453 ··· 1484 if (state != SLSB_CU_OUTPUT_PRIMED) 1485 rc = qdio_kick_outbound_q(q); 1486 else 1487 + qperf_inc(q, fast_requeue); 1488 1489 out: 1490 tasklet_schedule(&q->tasklet); ··· 1540 rc = qdio_debug_init(); 1541 if (rc) 1542 goto out_ti; 1543 rc = tiqdio_register_thinints(); 1544 if (rc) 1545 + goto out_debug; 1546 return 0; 1547 1548 out_debug: 1549 qdio_debug_exit(); 1550 out_ti: ··· 1563 { 1564 tiqdio_unregister_thinints(); 1565 tiqdio_free_memory(); 1566 qdio_debug_exit(); 1567 qdio_setup_exit(); 1568 }
-149
drivers/s390/cio/qdio_perf.c
··· 1 - /* 2 - * drivers/s390/cio/qdio_perf.c 3 - * 4 - * Copyright IBM Corp. 2008 5 - * 6 - * Author: Jan Glauber (jang@linux.vnet.ibm.com) 7 - */ 8 - #include <linux/kernel.h> 9 - #include <linux/proc_fs.h> 10 - #include <linux/seq_file.h> 11 - #include <asm/ccwdev.h> 12 - 13 - #include "cio.h" 14 - #include "css.h" 15 - #include "device.h" 16 - #include "ioasm.h" 17 - #include "chsc.h" 18 - #include "qdio_debug.h" 19 - #include "qdio_perf.h" 20 - 21 - int qdio_performance_stats; 22 - struct qdio_perf_stats perf_stats; 23 - 24 - #ifdef CONFIG_PROC_FS 25 - static struct proc_dir_entry *qdio_perf_pde; 26 - #endif 27 - 28 - /* 29 - * procfs functions 30 - */ 31 - static int qdio_perf_proc_show(struct seq_file *m, void *v) 32 - { 33 - seq_printf(m, "Number of qdio interrupts\t\t\t: %li\n", 34 - (long)atomic_long_read(&perf_stats.qdio_int)); 35 - seq_printf(m, "Number of PCI interrupts\t\t\t: %li\n", 36 - (long)atomic_long_read(&perf_stats.pci_int)); 37 - seq_printf(m, "Number of adapter interrupts\t\t\t: %li\n", 38 - (long)atomic_long_read(&perf_stats.thin_int)); 39 - seq_printf(m, "\n"); 40 - seq_printf(m, "Inbound tasklet runs\t\t\t\t: %li\n", 41 - (long)atomic_long_read(&perf_stats.tasklet_inbound)); 42 - seq_printf(m, "Outbound tasklet runs\t\t\t\t: %li\n", 43 - (long)atomic_long_read(&perf_stats.tasklet_outbound)); 44 - seq_printf(m, "Adapter interrupt tasklet runs/loops\t\t: %li/%li\n", 45 - (long)atomic_long_read(&perf_stats.tasklet_thinint), 46 - (long)atomic_long_read(&perf_stats.tasklet_thinint_loop)); 47 - seq_printf(m, "Adapter interrupt inbound tasklet runs/loops\t: %li/%li\n", 48 - (long)atomic_long_read(&perf_stats.thinint_inbound), 49 - (long)atomic_long_read(&perf_stats.thinint_inbound_loop)); 50 - seq_printf(m, "\n"); 51 - seq_printf(m, "Number of SIGA In issued\t\t\t: %li\n", 52 - (long)atomic_long_read(&perf_stats.siga_in)); 53 - seq_printf(m, "Number of SIGA Out issued\t\t\t: %li\n", 54 - (long)atomic_long_read(&perf_stats.siga_out)); 55 - seq_printf(m, "Number of SIGA Sync issued\t\t\t: %li\n", 56 - (long)atomic_long_read(&perf_stats.siga_sync)); 57 - seq_printf(m, "\n"); 58 - seq_printf(m, "Number of inbound transfers\t\t\t: %li\n", 59 - (long)atomic_long_read(&perf_stats.inbound_handler)); 60 - seq_printf(m, "Number of outbound transfers\t\t\t: %li\n", 61 - (long)atomic_long_read(&perf_stats.outbound_handler)); 62 - seq_printf(m, "\n"); 63 - seq_printf(m, "Number of fast requeues (outg. SBAL w/o SIGA)\t: %li\n", 64 - (long)atomic_long_read(&perf_stats.fast_requeue)); 65 - seq_printf(m, "Number of outbound target full condition\t: %li\n", 66 - (long)atomic_long_read(&perf_stats.outbound_target_full)); 67 - seq_printf(m, "Number of inbound queue full condition\t\t: %li\n", 68 - (long)atomic_long_read(&perf_stats.inbound_queue_full)); 69 - seq_printf(m, "Number of outbound tasklet mod_timer calls\t: %li\n", 70 - (long)atomic_long_read(&perf_stats.debug_tl_out_timer)); 71 - seq_printf(m, "Number of stop polling calls\t\t\t: %li\n", 72 - (long)atomic_long_read(&perf_stats.debug_stop_polling)); 73 - seq_printf(m, "AI inbound tasklet loops after stop polling\t: %li\n", 74 - (long)atomic_long_read(&perf_stats.thinint_inbound_loop2)); 75 - seq_printf(m, "QEBSM EQBS total/incomplete\t\t\t: %li/%li\n", 76 - (long)atomic_long_read(&perf_stats.debug_eqbs_all), 77 - (long)atomic_long_read(&perf_stats.debug_eqbs_incomplete)); 78 - seq_printf(m, "QEBSM SQBS total/incomplete\t\t\t: %li/%li\n", 79 - (long)atomic_long_read(&perf_stats.debug_sqbs_all), 80 - (long)atomic_long_read(&perf_stats.debug_sqbs_incomplete)); 81 - seq_printf(m, "\n"); 82 - return 0; 83 - } 84 - static int qdio_perf_seq_open(struct inode *inode, struct file *filp) 85 - { 86 - return single_open(filp, qdio_perf_proc_show, NULL); 87 - } 88 - 89 - static const struct file_operations qdio_perf_proc_fops = { 90 - .owner = THIS_MODULE, 91 - .open = qdio_perf_seq_open, 92 - .read = seq_read, 93 - .llseek = seq_lseek, 94 - .release = single_release, 95 - }; 96 - 97 - /* 98 - * sysfs functions 99 - */ 100 - static ssize_t qdio_perf_stats_show(struct bus_type *bus, char *buf) 101 - { 102 - return sprintf(buf, "%i\n", qdio_performance_stats ? 1 : 0); 103 - } 104 - 105 - static ssize_t qdio_perf_stats_store(struct bus_type *bus, 106 - const char *buf, size_t count) 107 - { 108 - unsigned long i; 109 - 110 - if (strict_strtoul(buf, 16, &i) != 0) 111 - return -EINVAL; 112 - if ((i != 0) && (i != 1)) 113 - return -EINVAL; 114 - if (i == qdio_performance_stats) 115 - return count; 116 - 117 - qdio_performance_stats = i; 118 - /* reset performance statistics */ 119 - if (i == 0) 120 - memset(&perf_stats, 0, sizeof(struct qdio_perf_stats)); 121 - return count; 122 - } 123 - 124 - static BUS_ATTR(qdio_performance_stats, 0644, qdio_perf_stats_show, 125 - qdio_perf_stats_store); 126 - 127 - int __init qdio_setup_perf_stats(void) 128 - { 129 - int rc; 130 - 131 - rc = bus_create_file(&ccw_bus_type, &bus_attr_qdio_performance_stats); 132 - if (rc) 133 - return rc; 134 - 135 - #ifdef CONFIG_PROC_FS 136 - memset(&perf_stats, 0, sizeof(struct qdio_perf_stats)); 137 - qdio_perf_pde = proc_create("qdio_perf", S_IFREG | S_IRUGO, 138 - NULL, &qdio_perf_proc_fops); 139 - #endif 140 - return 0; 141 - } 142 - 143 - void qdio_remove_perf_stats(void) 144 - { 145 - #ifdef CONFIG_PROC_FS 146 - remove_proc_entry("qdio_perf", NULL); 147 - #endif 148 - bus_remove_file(&ccw_bus_type, &bus_attr_qdio_performance_stats); 149 - }
···
-62
drivers/s390/cio/qdio_perf.h
··· 1 - /* 2 - * drivers/s390/cio/qdio_perf.h 3 - * 4 - * Copyright IBM Corp. 2008 5 - * 6 - * Author: Jan Glauber (jang@linux.vnet.ibm.com) 7 - */ 8 - #ifndef QDIO_PERF_H 9 - #define QDIO_PERF_H 10 - 11 - #include <linux/types.h> 12 - #include <asm/atomic.h> 13 - 14 - struct qdio_perf_stats { 15 - /* interrupt handler calls */ 16 - atomic_long_t qdio_int; 17 - atomic_long_t pci_int; 18 - atomic_long_t thin_int; 19 - 20 - /* tasklet runs */ 21 - atomic_long_t tasklet_inbound; 22 - atomic_long_t tasklet_outbound; 23 - atomic_long_t tasklet_thinint; 24 - atomic_long_t tasklet_thinint_loop; 25 - atomic_long_t thinint_inbound; 26 - atomic_long_t thinint_inbound_loop; 27 - atomic_long_t thinint_inbound_loop2; 28 - 29 - /* signal adapter calls */ 30 - atomic_long_t siga_out; 31 - atomic_long_t siga_in; 32 - atomic_long_t siga_sync; 33 - 34 - /* misc */ 35 - atomic_long_t inbound_handler; 36 - atomic_long_t outbound_handler; 37 - atomic_long_t fast_requeue; 38 - atomic_long_t outbound_target_full; 39 - atomic_long_t inbound_queue_full; 40 - 41 - /* for debugging */ 42 - atomic_long_t debug_tl_out_timer; 43 - atomic_long_t debug_stop_polling; 44 - atomic_long_t debug_eqbs_all; 45 - atomic_long_t debug_eqbs_incomplete; 46 - atomic_long_t debug_sqbs_all; 47 - atomic_long_t debug_sqbs_incomplete; 48 - }; 49 - 50 - extern struct qdio_perf_stats perf_stats; 51 - extern int qdio_performance_stats; 52 - 53 - static inline void qdio_perf_stat_inc(atomic_long_t *count) 54 - { 55 - if (qdio_performance_stats) 56 - atomic_long_inc(count); 57 - } 58 - 59 - int qdio_setup_perf_stats(void); 60 - void qdio_remove_perf_stats(void); 61 - 62 - #endif
···
+2 -6
drivers/s390/cio/qdio_thinint.c
··· 1 /* 2 * linux/drivers/s390/cio/thinint_qdio.c 3 * 4 - * thin interrupt support for qdio 5 - * 6 - * Copyright 2000-2008 IBM Corp. 7 * Author(s): Utz Bacher <utz.bacher@de.ibm.com> 8 * Cornelia Huck <cornelia.huck@de.ibm.com> 9 * Jan Glauber <jang@linux.vnet.ibm.com> ··· 17 #include "ioasm.h" 18 #include "qdio.h" 19 #include "qdio_debug.h" 20 - #include "qdio_perf.h" 21 22 /* 23 * Restriction: only 63 iqdio subchannels would have its own indicator, ··· 129 { 130 struct qdio_q *q; 131 132 - qdio_perf_stat_inc(&perf_stats.thin_int); 133 - 134 /* 135 * SVS only when needed: issue SVS to benefit from iqdio interrupt 136 * avoidance (SVS clears adapter interrupt suppression overwrite) ··· 149 list_for_each_entry_rcu(q, &tiq_list, entry) 150 /* only process queues from changed sets */ 151 if (*q->irq_ptr->dsci) { 152 153 /* only clear it if the indicator is non-shared */ 154 if (!shared_ind(q->irq_ptr))
··· 1 /* 2 * linux/drivers/s390/cio/thinint_qdio.c 3 * 4 + * Copyright 2000,2009 IBM Corp. 5 * Author(s): Utz Bacher <utz.bacher@de.ibm.com> 6 * Cornelia Huck <cornelia.huck@de.ibm.com> 7 * Jan Glauber <jang@linux.vnet.ibm.com> ··· 19 #include "ioasm.h" 20 #include "qdio.h" 21 #include "qdio_debug.h" 22 23 /* 24 * Restriction: only 63 iqdio subchannels would have its own indicator, ··· 132 { 133 struct qdio_q *q; 134 135 /* 136 * SVS only when needed: issue SVS to benefit from iqdio interrupt 137 * avoidance (SVS clears adapter interrupt suppression overwrite) ··· 154 list_for_each_entry_rcu(q, &tiq_list, entry) 155 /* only process queues from changed sets */ 156 if (*q->irq_ptr->dsci) { 157 + qperf_inc(q, adapter_int); 158 159 /* only clear it if the indicator is non-shared */ 160 if (!shared_ind(q->irq_ptr))