From: Frank Ch. Eigler Date: Thu, 6 May 2010 17:04:11 +0000 (-0400) Subject: PR11575: lengthen TRYLOCKDELAY X-Git-Tag: release-1.3~374 X-Git-Url: https://sourceware.org/git/?a=commitdiff_plain;h=26f62be4d9b2cfc975a07b96b988da2a62c30b71;p=systemtap.git PR11575: lengthen TRYLOCKDELAY Change default timeout for global variable locks to apprx. 1 ms, in 10us chunks. TRYLOCKDELAY now measures microseconds. * translate.cxx (translate_pass): Change TRYLOCKDELAY and MAXTRYLOCK default values. * runtime/probe_lock.h (stp_lock_probe): Use udelay() rather than ndelay(). * runtime/time.c (STP_TIMELOCK*): New macros just for time seqlock timeout purposes. Expected contention is negligible here. --- diff --git a/runtime/probe_lock.h b/runtime/probe_lock.h index 1077f4c60..f1c86f7da 100644 --- a/runtime/probe_lock.h +++ b/runtime/probe_lock.h @@ -1,5 +1,5 @@ /* probe locking header file - * Copyright (C) 2009 Red Hat Inc. + * Copyright (C) 2009-2010 Red Hat Inc. * * This file is part of systemtap, and is free software. You can * redistribute it and/or modify it under the terms of the GNU General @@ -48,13 +48,13 @@ stp_lock_probe(const struct stp_probe_lock *locks, unsigned num_locks) while (!write_trylock(locks[i].lock)) { if (++retries > MAXTRYLOCK) goto skip; - ndelay (TRYLOCKDELAY); + udelay (TRYLOCKDELAY); } else while (!read_trylock(locks[i].lock)) { if (++retries > MAXTRYLOCK) goto skip; - ndelay (TRYLOCKDELAY); + udelay (TRYLOCKDELAY); } } return 1; diff --git a/runtime/time.c b/runtime/time.c index 5caa73cc4..0d13487f3 100644 --- a/runtime/time.c +++ b/runtime/time.c @@ -269,6 +269,14 @@ _stp_init_time(void) return ret; } + +#ifndef STP_TIMELOCKDELAY +#define STP_TIMELOCKDELAY 100 /* ns */ +#endif +#ifndef STP_TIMELOCKTRIES +#define STP_TIMELOCKTRIES 10 /* total 1 us */ +#endif + static int64_t _stp_gettimeofday_ns(void) { @@ -283,17 +291,20 @@ _stp_gettimeofday_ns(void) if (!stp_time) return -1; - preempt_disable(); + preempt_disable(); /* XXX: why? Isn't this is only run from probe handlers? */ time = per_cpu_ptr(stp_time, smp_processor_id()); seq = read_seqbegin(&time->lock); base = time->base_ns; last = time->base_cycles; freq = time->freq; - while (unlikely(read_seqretry(&time->lock, seq))) { - if (unlikely(++i >= MAXTRYLOCK)) - return 0; - ndelay(TRYLOCKDELAY); + while (unlikely(read_seqretry(&time->lock, seq))) { + if (/* very */ unlikely(++i >= STP_TIMELOCKTRIES)) { + preempt_enable_no_resched(); + _stp_warn ("_stp_gettimofday_ns seqlock timeout; see STP_TIMELOCK*"); + return 0; + } + ndelay(STP_TIMELOCKDELAY); seq = read_seqbegin(&time->lock); base = time->base_ns; last = time->base_cycles; diff --git a/translate.cxx b/translate.cxx index b4d727c72..483d779a7 100644 --- a/translate.cxx +++ b/translate.cxx @@ -5459,11 +5459,11 @@ translate_pass (systemtap_session& s) s.op->newline() << "#ifndef MAXACTION_INTERRUPTIBLE"; s.op->newline() << "#define MAXACTION_INTERRUPTIBLE (MAXACTION * 10)"; s.op->newline() << "#endif"; - s.op->newline() << "#ifndef MAXTRYLOCK"; - s.op->newline() << "#define MAXTRYLOCK MAXACTION"; - s.op->newline() << "#endif"; s.op->newline() << "#ifndef TRYLOCKDELAY"; - s.op->newline() << "#define TRYLOCKDELAY 100"; + s.op->newline() << "#define TRYLOCKDELAY 10 /* microseconds */"; + s.op->newline() << "#endif"; + s.op->newline() << "#ifndef MAXTRYLOCK"; + s.op->newline() << "#define MAXTRYLOCK 100 /* 1 millisecond total */"; s.op->newline() << "#endif"; s.op->newline() << "#ifndef MAXMAPENTRIES"; s.op->newline() << "#define MAXMAPENTRIES 2048";