Skip to content

Commit

Permalink
s390/diag: add a statistic for diagnose calls
Browse files Browse the repository at this point in the history
Introduce /sys/debug/kernel/diag_stat with a statistic how many diagnose
calls have been done by each CPU in the system.

Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
  • Loading branch information
Martin Schwidefsky committed Oct 14, 2015
1 parent acdc9fc commit 1ec2772
Show file tree
Hide file tree
Showing 19 changed files with 282 additions and 19 deletions.
10 changes: 9 additions & 1 deletion arch/s390/hypfs/hypfs_diag.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <linux/string.h>
#include <linux/vmalloc.h>
#include <linux/mm.h>
#include <asm/diag.h>
#include <asm/ebcdic.h>
#include "hypfs.h"

Expand Down Expand Up @@ -336,7 +337,7 @@ static inline __u64 phys_cpu__ctidx(enum diag204_format type, void *hdr)

/* Diagnose 204 functions */

static int diag204(unsigned long subcode, unsigned long size, void *addr)
static inline int __diag204(unsigned long subcode, unsigned long size, void *addr)
{
register unsigned long _subcode asm("0") = subcode;
register unsigned long _size asm("1") = size;
Expand All @@ -351,6 +352,12 @@ static int diag204(unsigned long subcode, unsigned long size, void *addr)
return _size;
}

static int diag204(unsigned long subcode, unsigned long size, void *addr)
{
diag_stat_inc(DIAG_STAT_X204);
return __diag204(subcode, size, addr);
}

/*
* For the old diag subcode 4 with simple data format we have to use real
* memory. If we use subcode 6 or 7 with extended data format, we can (and
Expand Down Expand Up @@ -505,6 +512,7 @@ static int diag224(void *ptr)
{
int rc = -EOPNOTSUPP;

diag_stat_inc(DIAG_STAT_X224);
asm volatile(
" diag %1,%2,0x224\n"
"0: lhi %0,0x0\n"
Expand Down
2 changes: 2 additions & 0 deletions arch/s390/hypfs/hypfs_diag0c.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include <linux/slab.h>
#include <linux/cpu.h>
#include <asm/diag.h>
#include <asm/hypfs.h>
#include "hypfs.h"

Expand All @@ -18,6 +19,7 @@
*/
static void diag0c(struct hypfs_diag0c_entry *entry)
{
diag_stat_inc(DIAG_STAT_X00C);
asm volatile (
" sam31\n"
" diag %0,%0,0x0c\n"
Expand Down
9 changes: 8 additions & 1 deletion arch/s390/hypfs/hypfs_sprp.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <linux/types.h>
#include <linux/uaccess.h>
#include <asm/compat.h>
#include <asm/diag.h>
#include <asm/sclp.h>
#include "hypfs.h"

Expand All @@ -22,7 +23,7 @@

#define DIAG304_CMD_MAX 2

static unsigned long hypfs_sprp_diag304(void *data, unsigned long cmd)
static inline unsigned long __hypfs_sprp_diag304(void *data, unsigned long cmd)
{
register unsigned long _data asm("2") = (unsigned long) data;
register unsigned long _rc asm("3");
Expand All @@ -34,6 +35,12 @@ static unsigned long hypfs_sprp_diag304(void *data, unsigned long cmd)
return _rc;
}

static unsigned long hypfs_sprp_diag304(void *data, unsigned long cmd)
{
diag_stat_inc(DIAG_STAT_X304);
return __hypfs_sprp_diag304(data, cmd);
}

static void hypfs_sprp_free(const void *data)
{
free_page((unsigned long) data);
Expand Down
2 changes: 2 additions & 0 deletions arch/s390/hypfs/hypfs_vm.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/vmalloc.h>
#include <asm/diag.h>
#include <asm/ebcdic.h>
#include <asm/timex.h>
#include "hypfs.h"
Expand Down Expand Up @@ -66,6 +67,7 @@ static int diag2fc(int size, char* query, void *addr)
memset(parm_list.aci_grp, 0x40, NAME_LEN);
rc = -1;

diag_stat_inc(DIAG_STAT_X2FC);
asm volatile(
" diag %0,%1,0x2fc\n"
"0:\n"
Expand Down
2 changes: 2 additions & 0 deletions arch/s390/include/asm/appldata.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#ifndef _ASM_S390_APPLDATA_H
#define _ASM_S390_APPLDATA_H

#include <asm/diag.h>
#include <asm/io.h>

#define APPLDATA_START_INTERVAL_REC 0x80
Expand Down Expand Up @@ -53,6 +54,7 @@ static inline int appldata_asm(struct appldata_product_id *id,
parm_list.buffer_length = length;
parm_list.product_id_addr = (unsigned long) id;
parm_list.buffer_addr = virt_to_phys(buffer);
diag_stat_inc(DIAG_STAT_X0DC);
asm volatile(
" diag %1,%0,0xdc"
: "=d" (ry)
Expand Down
37 changes: 37 additions & 0 deletions arch/s390/include/asm/diag.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,42 @@
#ifndef _ASM_S390_DIAG_H
#define _ASM_S390_DIAG_H

#include <linux/percpu.h>

enum diag_stat_enum {
DIAG_STAT_X008,
DIAG_STAT_X00C,
DIAG_STAT_X010,
DIAG_STAT_X014,
DIAG_STAT_X044,
DIAG_STAT_X064,
DIAG_STAT_X09C,
DIAG_STAT_X0DC,
DIAG_STAT_X204,
DIAG_STAT_X210,
DIAG_STAT_X224,
DIAG_STAT_X250,
DIAG_STAT_X258,
DIAG_STAT_X288,
DIAG_STAT_X2C4,
DIAG_STAT_X2FC,
DIAG_STAT_X304,
DIAG_STAT_X308,
DIAG_STAT_X500,
NR_DIAG_STAT
};

struct diag_stat {
unsigned int counter[NR_DIAG_STAT];
};

DECLARE_PER_CPU(struct diag_stat, diag_stat);

static inline void diag_stat_inc(enum diag_stat_enum nr)
{
this_cpu_inc(diag_stat.counter[nr]);
}

/*
* Diagnose 10: Release page range
*/
Expand All @@ -18,6 +54,7 @@ static inline void diag10_range(unsigned long start_pfn, unsigned long num_pfn)
start_addr = start_pfn << PAGE_SHIFT;
end_addr = (start_pfn + num_pfn - 1) << PAGE_SHIFT;

diag_stat_inc(DIAG_STAT_X010);
asm volatile(
"0: diag %0,%1,0x10\n"
"1:\n"
Expand Down
67 changes: 58 additions & 9 deletions arch/s390/include/asm/kvm_para.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,9 @@
#define __S390_KVM_PARA_H

#include <uapi/asm/kvm_para.h>
#include <asm/diag.h>



static inline long kvm_hypercall0(unsigned long nr)
static inline long __kvm_hypercall0(unsigned long nr)
{
register unsigned long __nr asm("1") = nr;
register long __rc asm("2");
Expand All @@ -40,7 +39,13 @@ static inline long kvm_hypercall0(unsigned long nr)
return __rc;
}

static inline long kvm_hypercall1(unsigned long nr, unsigned long p1)
static inline long kvm_hypercall0(unsigned long nr)
{
diag_stat_inc(DIAG_STAT_X500);
return __kvm_hypercall0(nr);
}

static inline long __kvm_hypercall1(unsigned long nr, unsigned long p1)
{
register unsigned long __nr asm("1") = nr;
register unsigned long __p1 asm("2") = p1;
Expand All @@ -51,7 +56,13 @@ static inline long kvm_hypercall1(unsigned long nr, unsigned long p1)
return __rc;
}

static inline long kvm_hypercall2(unsigned long nr, unsigned long p1,
static inline long kvm_hypercall1(unsigned long nr, unsigned long p1)
{
diag_stat_inc(DIAG_STAT_X500);
return __kvm_hypercall1(nr, p1);
}

static inline long __kvm_hypercall2(unsigned long nr, unsigned long p1,
unsigned long p2)
{
register unsigned long __nr asm("1") = nr;
Expand All @@ -65,7 +76,14 @@ static inline long kvm_hypercall2(unsigned long nr, unsigned long p1,
return __rc;
}

static inline long kvm_hypercall3(unsigned long nr, unsigned long p1,
static inline long kvm_hypercall2(unsigned long nr, unsigned long p1,
unsigned long p2)
{
diag_stat_inc(DIAG_STAT_X500);
return __kvm_hypercall2(nr, p1, p2);
}

static inline long __kvm_hypercall3(unsigned long nr, unsigned long p1,
unsigned long p2, unsigned long p3)
{
register unsigned long __nr asm("1") = nr;
Expand All @@ -80,8 +98,14 @@ static inline long kvm_hypercall3(unsigned long nr, unsigned long p1,
return __rc;
}

static inline long kvm_hypercall3(unsigned long nr, unsigned long p1,
unsigned long p2, unsigned long p3)
{
diag_stat_inc(DIAG_STAT_X500);
return __kvm_hypercall3(nr, p1, p2, p3);
}

static inline long kvm_hypercall4(unsigned long nr, unsigned long p1,
static inline long __kvm_hypercall4(unsigned long nr, unsigned long p1,
unsigned long p2, unsigned long p3,
unsigned long p4)
{
Expand All @@ -98,7 +122,15 @@ static inline long kvm_hypercall4(unsigned long nr, unsigned long p1,
return __rc;
}

static inline long kvm_hypercall5(unsigned long nr, unsigned long p1,
static inline long kvm_hypercall4(unsigned long nr, unsigned long p1,
unsigned long p2, unsigned long p3,
unsigned long p4)
{
diag_stat_inc(DIAG_STAT_X500);
return __kvm_hypercall4(nr, p1, p2, p3, p4);
}

static inline long __kvm_hypercall5(unsigned long nr, unsigned long p1,
unsigned long p2, unsigned long p3,
unsigned long p4, unsigned long p5)
{
Expand All @@ -116,7 +148,15 @@ static inline long kvm_hypercall5(unsigned long nr, unsigned long p1,
return __rc;
}

static inline long kvm_hypercall6(unsigned long nr, unsigned long p1,
static inline long kvm_hypercall5(unsigned long nr, unsigned long p1,
unsigned long p2, unsigned long p3,
unsigned long p4, unsigned long p5)
{
diag_stat_inc(DIAG_STAT_X500);
return __kvm_hypercall5(nr, p1, p2, p3, p4, p5);
}

static inline long __kvm_hypercall6(unsigned long nr, unsigned long p1,
unsigned long p2, unsigned long p3,
unsigned long p4, unsigned long p5,
unsigned long p6)
Expand All @@ -137,6 +177,15 @@ static inline long kvm_hypercall6(unsigned long nr, unsigned long p1,
return __rc;
}

static inline long kvm_hypercall6(unsigned long nr, unsigned long p1,
unsigned long p2, unsigned long p3,
unsigned long p4, unsigned long p5,
unsigned long p6)
{
diag_stat_inc(DIAG_STAT_X500);
return __kvm_hypercall6(nr, p1, p2, p3, p4, p5, p6);
}

/* kvm on s390 is always paravirtualization enabled */
static inline int kvm_para_available(void)
{
Expand Down
2 changes: 2 additions & 0 deletions arch/s390/kernel/cpcmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <linux/spinlock.h>
#include <linux/stddef.h>
#include <linux/string.h>
#include <asm/diag.h>
#include <asm/ebcdic.h>
#include <asm/cpcmd.h>
#include <asm/io.h>
Expand Down Expand Up @@ -70,6 +71,7 @@ int __cpcmd(const char *cmd, char *response, int rlen, int *response_code)
memcpy(cpcmd_buf, cmd, cmdlen);
ASCEBC(cpcmd_buf, cmdlen);

diag_stat_inc(DIAG_STAT_X008);
if (response) {
memset(response, 0, rlen);
response_len = rlen;
Expand Down
Loading

0 comments on commit 1ec2772

Please sign in to comment.