Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 65314
b: refs/heads/master
c: 85923b1
h: refs/heads/master
v: v3
  • Loading branch information
Linus Torvalds committed Oct 7, 2007
1 parent a03ca3d commit 1fbb726
Show file tree
Hide file tree
Showing 11 changed files with 201 additions and 23 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: a1134dd48d59e532b801659163539bf01cae7673
refs/heads/master: 85923b124624eb49ebef4731bb6b5670e792ff57
120 changes: 120 additions & 0 deletions trunk/Documentation/lockstat.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@

LOCK STATISTICS

- WHAT

As the name suggests, it provides statistics on locks.

- WHY

Because things like lock contention can severely impact performance.

- HOW

Lockdep already has hooks in the lock functions and maps lock instances to
lock classes. We build on that. The graph below shows the relation between
the lock functions and the various hooks therein.

__acquire
|
lock _____
| \
| __contended
| |
| <wait>
| _______/
|/
|
__acquired
|
.
<hold>
.
|
__release
|
unlock

lock, unlock - the regular lock functions
__* - the hooks
<> - states

With these hooks we provide the following statistics:

con-bounces - number of lock contention that involved x-cpu data
contentions - number of lock acquisitions that had to wait
wait time min - shortest (non-0) time we ever had to wait for a lock
max - longest time we ever had to wait for a lock
total - total time we spend waiting on this lock
acq-bounces - number of lock acquisitions that involved x-cpu data
acquisitions - number of times we took the lock
hold time min - shortest (non-0) time we ever held the lock
max - longest time we ever held the lock
total - total time this lock was held

From these number various other statistics can be derived, such as:

hold time average = hold time total / acquisitions

These numbers are gathered per lock class, per read/write state (when
applicable).

It also tracks 4 contention points per class. A contention point is a call site
that had to wait on lock acquisition.

- USAGE

Look at the current lock statistics:

( line numbers not part of actual output, done for clarity in the explanation
below )

# less /proc/lock_stat

01 lock_stat version 0.2
02 -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
03 class name con-bounces contentions waittime-min waittime-max waittime-total acq-bounces acquisitions holdtime-min holdtime-max holdtime-total
04 -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
05
06 &inode->i_data.tree_lock-W: 15 21657 0.18 1093295.30 11547131054.85 58 10415 0.16 87.51 6387.60
07 &inode->i_data.tree_lock-R: 0 0 0.00 0.00 0.00 23302 231198 0.25 8.45 98023.38
08 --------------------------
09 &inode->i_data.tree_lock 0 [<ffffffff8027c08f>] add_to_page_cache+0x5f/0x190
10
11 ...............................................................................................................................................................................................
12
13 dcache_lock: 1037 1161 0.38 45.32 774.51 6611 243371 0.15 306.48 77387.24
14 -----------
15 dcache_lock 180 [<ffffffff802c0d7e>] sys_getcwd+0x11e/0x230
16 dcache_lock 165 [<ffffffff802c002a>] d_alloc+0x15a/0x210
17 dcache_lock 33 [<ffffffff8035818d>] _atomic_dec_and_lock+0x4d/0x70
18 dcache_lock 1 [<ffffffff802beef8>] shrink_dcache_parent+0x18/0x130

This excerpt shows the first two lock class statistics. Line 01 shows the
output version - each time the format changes this will be updated. Line 02-04
show the header with column descriptions. Lines 05-10 and 13-18 show the actual
statistics. These statistics come in two parts; the actual stats separated by a
short separator (line 08, 14) from the contention points.

The first lock (05-10) is a read/write lock, and shows two lines above the
short separator. The contention points don't match the column descriptors,
they have two: contentions and [<IP>] symbol.


View the top contending locks:

# grep : /proc/lock_stat | head
&inode->i_data.tree_lock-W: 15 21657 0.18 1093295.30 11547131054.85 58 10415 0.16 87.51 6387.60
&inode->i_data.tree_lock-R: 0 0 0.00 0.00 0.00 23302 231198 0.25 8.45 98023.38
dcache_lock: 1037 1161 0.38 45.32 774.51 6611 243371 0.15 306.48 77387.24
&inode->i_mutex: 161 286 18446744073709 62882.54 1244614.55 3653 20598 18446744073709 62318.60 1693822.74
&zone->lru_lock: 94 94 0.53 7.33 92.10 4366 32690 0.29 59.81 16350.06
&inode->i_data.i_mmap_lock: 79 79 0.40 3.77 53.03 11779 87755 0.28 116.93 29898.44
&q->__queue_lock: 48 50 0.52 31.62 86.31 774 13131 0.17 113.08 12277.52
&rq->rq_lock_key: 43 47 0.74 68.50 170.63 3706 33929 0.22 107.99 17460.62
&rq->rq_lock_key#2: 39 46 0.75 6.68 49.03 2979 32292 0.17 125.17 17137.63
tasklist_lock-W: 15 15 1.45 10.87 32.70 1201 7390 0.58 62.55 13648.47

Clear the statistics:

# echo 0 > /proc/lock_stat
2 changes: 1 addition & 1 deletion trunk/Documentation/sysrq.txt
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ On x86 - You press the key combo 'ALT-SysRq-<command key>'. Note - Some
keyboards may not have a key labeled 'SysRq'. The 'SysRq' key is
also known as the 'Print Screen' key. Also some keyboards cannot
handle so many keys being pressed at the same time, so you might
have better luck with "press Alt", "press SysRq", "release Alt",
have better luck with "press Alt", "press SysRq", "release SysRq",
"press <command key>", release everything.

On SPARC - You press 'ALT-STOP-<command key>', I believe.
Expand Down
60 changes: 57 additions & 3 deletions trunk/arch/i386/kernel/cpu/cpufreq/longhaul.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ static unsigned int longhaul_index;
/* Module parameters */
static int scale_voltage;
static int disable_acpi_c3;
static int revid_errata;

#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "longhaul", msg)

Expand Down Expand Up @@ -168,7 +169,10 @@ static void do_powersaver(int cx_address, unsigned int clock_ratio_index,

rdmsrl(MSR_VIA_LONGHAUL, longhaul.val);
/* Setup new frequency */
longhaul.bits.RevisionKey = longhaul.bits.RevisionID;
if (!revid_errata)
longhaul.bits.RevisionKey = longhaul.bits.RevisionID;
else
longhaul.bits.RevisionKey = 0;
longhaul.bits.SoftBusRatio = clock_ratio_index & 0xf;
longhaul.bits.SoftBusRatio4 = (clock_ratio_index & 0x10) >> 4;
/* Setup new voltage */
Expand Down Expand Up @@ -272,7 +276,7 @@ static void longhaul_setstate(unsigned int table_index)

dprintk ("Setting to FSB:%dMHz Mult:%d.%dx (%s)\n",
fsb, mult/10, mult%10, print_speed(speed/1000));

retry_loop:
preempt_disable();
local_irq_save(flags);

Expand Down Expand Up @@ -344,6 +348,47 @@ static void longhaul_setstate(unsigned int table_index)
preempt_enable();

freqs.new = calc_speed(longhaul_get_cpu_mult());
/* Check if requested frequency is set. */
if (unlikely(freqs.new != speed)) {
printk(KERN_INFO PFX "Failed to set requested frequency!\n");
/* Revision ID = 1 but processor is expecting revision key
* equal to 0. Jumpers at the bottom of processor will change
* multiplier and FSB, but will not change bits in Longhaul
* MSR nor enable voltage scaling. */
if (!revid_errata) {
printk(KERN_INFO PFX "Enabling \"Ignore Revision ID\" "
"option.\n");
revid_errata = 1;
msleep(200);
goto retry_loop;
}
/* Why ACPI C3 sometimes doesn't work is a mystery for me.
* But it does happen. Processor is entering ACPI C3 state,
* but it doesn't change frequency. I tried poking various
* bits in northbridge registers, but without success. */
if (longhaul_flags & USE_ACPI_C3) {
printk(KERN_INFO PFX "Disabling ACPI C3 support.\n");
longhaul_flags &= ~USE_ACPI_C3;
if (revid_errata) {
printk(KERN_INFO PFX "Disabling \"Ignore "
"Revision ID\" option.\n");
revid_errata = 0;
}
msleep(200);
goto retry_loop;
}
/* This shouldn't happen. Longhaul ver. 2 was reported not
* working on processors without voltage scaling, but with
* RevID = 1. RevID errata will make things right. Just
* to be 100% sure. */
if (longhaul_version == TYPE_LONGHAUL_V2) {
printk(KERN_INFO PFX "Switching to Longhaul ver. 1\n");
longhaul_version = TYPE_LONGHAUL_V1;
msleep(200);
goto retry_loop;
}
}
/* Report true CPU frequency */
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);

if (!bm_timeout)
Expand Down Expand Up @@ -956,11 +1001,20 @@ static void __exit longhaul_exit(void)
kfree(longhaul_table);
}

/* Even if BIOS is exporting ACPI C3 state, and it is used
* with success when CPU is idle, this state doesn't
* trigger frequency transition in some cases. */
module_param (disable_acpi_c3, int, 0644);
MODULE_PARM_DESC(disable_acpi_c3, "Don't use ACPI C3 support");

/* Change CPU voltage with frequency. Very usefull to save
* power, but most VIA C3 processors aren't supporting it. */
module_param (scale_voltage, int, 0644);
MODULE_PARM_DESC(scale_voltage, "Scale voltage of processor");
/* Force revision key to 0 for processors which doesn't
* support voltage scaling, but are introducing itself as
* such. */
module_param(revid_errata, int, 0644);
MODULE_PARM_DESC(revid_errata, "Ignore CPU Revision ID");

MODULE_AUTHOR ("Dave Jones <davej@codemonkey.org.uk>");
MODULE_DESCRIPTION ("Longhaul driver for VIA Cyrix processors.");
Expand Down
4 changes: 2 additions & 2 deletions trunk/drivers/char/vt_ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1032,7 +1032,7 @@ static DECLARE_WAIT_QUEUE_HEAD(vt_activate_queue);

/*
* Sleeps until a vt is activated, or the task is interrupted. Returns
* 0 if activation, -EINTR if interrupted.
* 0 if activation, -EINTR if interrupted by a signal handler.
*/
int vt_waitactive(int vt)
{
Expand All @@ -1057,7 +1057,7 @@ int vt_waitactive(int vt)
break;
}
release_console_sem();
retval = -EINTR;
retval = -ERESTARTNOHAND;
if (signal_pending(current))
break;
schedule();
Expand Down
1 change: 1 addition & 0 deletions trunk/drivers/serial/serial_cs.c
Original file line number Diff line number Diff line change
Expand Up @@ -943,6 +943,7 @@ static struct pcmcia_device_id serial_ids[] = {
PCMCIA_MFC_DEVICE_PROD_ID12(1,"Elan","Serial Port: SL432",0x3beb8cf2,0x1cce7ac4),
PCMCIA_MFC_DEVICE_PROD_ID12(2,"Elan","Serial Port: SL432",0x3beb8cf2,0x1cce7ac4),
PCMCIA_MFC_DEVICE_PROD_ID12(3,"Elan","Serial Port: SL432",0x3beb8cf2,0x1cce7ac4),
PCMCIA_DEVICE_MANF_CARD(0x0279, 0x950b),
/* too generic */
/* PCMCIA_MFC_DEVICE_MANF_CARD(0, 0x0160, 0x0002), */
/* PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0160, 0x0002), */
Expand Down
2 changes: 1 addition & 1 deletion trunk/include/linux/sched.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ extern unsigned long avenrun[]; /* Load averages */

#define FSHIFT 11 /* nr of bits of precision */
#define FIXED_1 (1<<FSHIFT) /* 1.0 as fixed-point */
#define LOAD_FREQ (5*HZ) /* 5 sec intervals */
#define LOAD_FREQ (5*HZ+1) /* 5 sec intervals */
#define EXP_1 1884 /* 1/exp(5sec/1min) as fixed-point */
#define EXP_5 2014 /* 1/exp(5sec/5min) */
#define EXP_15 2037 /* 1/exp(5sec/15min) */
Expand Down
22 changes: 11 additions & 11 deletions trunk/kernel/signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -531,18 +531,18 @@ static int check_kill_permission(int sig, struct siginfo *info,
if (!valid_signal(sig))
return error;

error = audit_signal_info(sig, t); /* Let audit system see the signal */
if (error)
return error;

error = -EPERM;
if ((info == SEND_SIG_NOINFO || (!is_si_special(info) && SI_FROMUSER(info)))
&& ((sig != SIGCONT) ||
(process_session(current) != process_session(t)))
&& (current->euid ^ t->suid) && (current->euid ^ t->uid)
&& (current->uid ^ t->suid) && (current->uid ^ t->uid)
&& !capable(CAP_KILL))
if (info == SEND_SIG_NOINFO || (!is_si_special(info) && SI_FROMUSER(info))) {
error = audit_signal_info(sig, t); /* Let audit system see the signal */
if (error)
return error;
error = -EPERM;
if (((sig != SIGCONT) ||
(process_session(current) != process_session(t)))
&& (current->euid ^ t->suid) && (current->euid ^ t->uid)
&& (current->uid ^ t->suid) && (current->uid ^ t->uid)
&& !capable(CAP_KILL))
return error;
}

return security_task_kill(t, info, sig, 0);
}
Expand Down
5 changes: 3 additions & 2 deletions trunk/kernel/time/timer_stats.c
Original file line number Diff line number Diff line change
Expand Up @@ -327,8 +327,9 @@ static int tstats_show(struct seq_file *m, void *v)
ms = 1;

if (events && period.tv_sec)
seq_printf(m, "%ld total events, %ld.%ld events/sec\n", events,
events / period.tv_sec, events * 1000 / ms);
seq_printf(m, "%ld total events, %ld.%03ld events/sec\n",
events, events * 1000 / ms,
(events * 1000000 / ms) % 1000);
else
seq_printf(m, "%ld total events\n", events);

Expand Down
2 changes: 2 additions & 0 deletions trunk/lib/Kconfig.debug
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,8 @@ config LOCK_STAT
help
This feature enables tracking lock contention points

For more details, see Documentation/lockstat.txt

config DEBUG_LOCKDEP
bool "Lock dependency engine debugging"
depends on DEBUG_KERNEL && LOCKDEP
Expand Down
4 changes: 2 additions & 2 deletions trunk/lib/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# Makefile for some libs needed in the kernel.
#

lib-y := ctype.o string.o vsprintf.o kasprintf.o cmdline.o \
lib-y := ctype.o string.o vsprintf.o cmdline.o \
rbtree.o radix-tree.o dump_stack.o \
idr.o int_sqrt.o bitmap.o extable.o prio_tree.o \
sha1.o irq_regs.o reciprocal_div.o argv_split.o
Expand All @@ -13,7 +13,7 @@ lib-$(CONFIG_SMP) += cpumask.o
lib-y += kobject.o kref.o kobject_uevent.o klist.o

obj-y += div64.o sort.o parser.o halfmd4.o debug_locks.o random32.o \
bust_spinlocks.o hexdump.o
bust_spinlocks.o hexdump.o kasprintf.o

ifeq ($(CONFIG_DEBUG_KOBJECT),y)
CFLAGS_kobject.o += -DDEBUG
Expand Down

0 comments on commit 1fbb726

Please sign in to comment.