LWN.net Logo

lockmeter for s390

From:  Thomas Weber <tweber@de.ibm.com>
To:  raybry@sgi.com
Subject:  [PATCH 1/2] lockmeter for s390
Date:  Wed, 08 Dec 2004 11:09:49 +0100
Cc:  akpm@osdl.org, lse-tech@lists.sourceforge.net
Archive-link:  Article, Thread

Ray,

after successful testing, I would like to introduce the lockmeter patch 
for the s390 platform.
This patch was tested with the kernel_2.6.8.1-mm4 version of the 
lockmeter patch.
Please check, if you can use the patch below for integration into the 
lockmeter patch.
I split the patch into two parts, because the second will affect the 
common lockmeter.h
file.

===============================================================
--- arch/s390/Kconfig    2004-10-12 13:18:28.000000000 +0200
+++ Kconfig     2004-11-15 13:07:38.125171516 +0100
@@ -537,6 +537,13 @@ config DEBUG_SPINLOCK_SLEEP
          If you say Y here, various routines which may sleep will 
become very
          noisy if they are called with a spinlock held.

+config LOCKMETER
+       bool "Kernel lock metering"
+       depends on SMP
+       help
+         Say Y to enable kernel lock metering, which adds overhead to 
SMP locks,
+         but allows you to see various statistics using the lockstat 
command.
+
 endmenu

 source "security/Kconfig"
--- include/asm-s390/spinlock.h 2004-06-16 16:34:46.000000000 +0200
+++ spinlock.h  2004-11-16 17:58:57.005171516 +0100
@@ -11,6 +11,11 @@
 #ifndef __ASM_SPINLOCK_H
 #define __ASM_SPINLOCK_H

+#ifdef CONFIG_LOCKMETER
+#undef DEBUG_SPINLOCK
+#undef DEBUG_RWLOCK
+#endif
+
 #ifdef __s390x__
 /*
  * Grmph, take care of %&#! user space programs that include
@@ -36,10 +41,17 @@

 typedef struct {
        volatile unsigned int lock;
+#ifdef CONFIG_LOCKMETER
+        volatile unsigned int index;
+#endif
 } __attribute__ ((aligned (4))) spinlock_t;

+#ifdef CONFIG_LOCKMETER
+#define SPIN_LOCK_UNLOCKED (spinlock_t) { 0, 0 }
+#else
 #define SPIN_LOCK_UNLOCKED (spinlock_t) { 0 }
-#define spin_lock_init(lp) do { (lp)->lock = 0; } while(0)
+#endif
+#define spin_lock_init(lp) do { *(lp) = SPIN_LOCK_UNLOCKED; } while(0)
 #define spin_unlock_wait(lp)   do { barrier(); } while(((volatile 
spinlock_t *)(lp))->lock)
 #define spin_is_locked(x) ((x)->lock != 0)
 #define _raw_spin_lock_flags(lock, flags) _raw_spin_lock(lock)
@@ -105,12 +117,18 @@ extern inline void _raw_spin_unlock(spin
 typedef struct {
        volatile unsigned long lock;
        volatile unsigned long owner_pc;
+#ifdef CONFIG_LOCKMETER
+        volatile unsigned long index;
+       volatile unsigned long cpu;
+#endif
 } rwlock_t;

+#ifdef CONFIG_LOCKMETER
+#define RW_LOCK_UNLOCKED (rwlock_t) { 0, 0, 0, 0xff }
+#else
 #define RW_LOCK_UNLOCKED (rwlock_t) { 0, 0 }
-
-#define rwlock_init(x) do { *(x) = RW_LOCK_UNLOCKED; } while(0)
-
+#endif
+#define rwlock_init(x)  do { *(x) = RW_LOCK_UNLOCKED; } while(0)
 #define rwlock_is_locked(x) ((x)->lock != 0)

 #ifndef __s390x__
@@ -230,4 +248,28 @@ extern inline int _raw_write_trylock(rwl
        return result == 0;
 }

+#ifdef CONFIG_LOCKMETER
+
+extern inline int _raw_read_trylock(rwlock_t *rw)
+{
+        unsigned long old, new;
+
+        __asm__ __volatile__(
+#ifndef __s390x__
+                             "   la   %0,0(%0)\n"
+                             "   la   %1,1(%0)\n"
+                             "   cs   %0,%1,0(%3)"
+#else /* __s390x__ */
+                             "   nihh %0,0x7fff\n"
+                             "   la   %1,1(%0)\n"
+                             "   csg %0,%1,0(%3)\n"
+#endif /* __s390x__ */
+                             : "=a" (old), "=&d" (new), "=m" (rw->lock)
+                             : "a" (&rw->lock), "m" (rw->lock), "0" 
(rw->lock)
+                             : "cc", "memory" );
+        return new == (old + 1);
+}
+
+#endif
+
 #endif /* __ASM_SPINLOCK_H */
--- /dev/null   2004-09-02 16:32:28.000000000 +0200
+++ include/asm-s390/lockmeter.h        2004-11-16 17:35:36.115171516 +0100
@@ -0,0 +1,69 @@
+/*
+ * (C) Copyright IBM Corp. 2004
+ *
+ * Based on the work of Maxim Shchetynin (maxim@de.ibm.com)
+ * Modified by Thomas Weber (tweber@de.ibm.com)
+ *
+ * s390 specific part of lockmeter.h
+ *
+*/
+
+#ifndef _S390_LOCKMETER_H
+#define _S390_LOCKMETER_H
+
+#include <asm/spinlock.h>
+#include <asm/timex.h>
+#include <asm/smp.h>
+
+/*
+ * s390 STCK resolution is 1 microsecond
+ * multiply with 1024 for get_cycles resolution
+ */
+#define CPU_CYCLE_FREQUENCY    1024000000
+
+#define get_cycles64()         get_cycles()
+
+#define THIS_CPU_NUMBER        smp_processor_id()
+
+/*
+ * macros to set and retrieve an index value for a spin lock
+ */
+#define PUT_INDEX(lock_ptr,indexv) \
+        ((spinlock_t*)(lock_ptr))->index = indexv
+#define GET_INDEX(lock_ptr) \
+        ((spinlock_t*)(lock_ptr))->index
+
+/*
+ * macros to set and retrieve an index value for a read/write lock
+ * as well as the cpu where a reader busy period started
+ */
+#define PUT_RWINDEX(rwlock_ptr,indexv) \
+       ((rwlock_t*)(rwlock_ptr))->index = indexv
+#define GET_RWINDEX(rwlock_ptr) \
+       ((rwlock_t*)(rwlock_ptr))->index
+#define PUT_RW_CPU(rwlock_ptr,cpuv) \
+       ((rwlock_t*)(rwlock_ptr))->cpu = cpuv
+#define GET_RW_CPU(rwlock_ptr) \
+       ((rwlock_t*)(rwlock_ptr))->cpu
+
+/*
+ * return the number of readers for a read/write lock
+ */
+#define RWLOCK_READERS(rwlock_ptr) rwlock_readers(rwlock_ptr)
+
+extern inline unsigned long rwlock_readers(rwlock_t *rwlock_ptr)
+{
+     unsigned long lock = rwlock_ptr->lock;
+     /* clear high (=write) bit == number of readers */
+     return lock << 1 >> 1;
+}
+
+/*
+ * return true if read/write lock is locked
+ */
+#define RWLOCK_IS_READ_LOCKED(rwlock_ptr) \
+       (((signed long)((rwlock_t*)rwlock_ptr)->lock) > 0)
+#define RWLOCK_IS_WRITE_LOCKED(rwlock_ptr) \
+       (((signed long)((rwlock_t*)rwlock_ptr)->lock) < 0)
+
+#endif /* _S390_LOCKMETER_H */
===============================================================

Regards,
Thomas Weber, IBM Germany



-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now. 
http://productguide.itmanagersjournal.com/

Copyright © 2004, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds