diff options
author | ddomingo <ddomingo@redhat.com> | 2008-09-22 11:40:58 +1000 |
---|---|---|
committer | ddomingo <ddomingo@redhat.com> | 2008-09-22 11:40:58 +1000 |
commit | 19c6b7ad6b1a468694d918cbd8a71bb6b60c22ce (patch) | |
tree | 3aebdaa1ae2cc005a0050406541ed428b61b1d99 /runtime | |
parent | ca74563434b2877cd2d7e7e81dc3919483cca694 (diff) | |
parent | e8ea4501122483436cdeb0352d833ccefeda7d14 (diff) | |
download | systemtap-steved-19c6b7ad6b1a468694d918cbd8a71bb6b60c22ce.tar.gz systemtap-steved-19c6b7ad6b1a468694d918cbd8a71bb6b60c22ce.tar.xz systemtap-steved-19c6b7ad6b1a468694d918cbd8a71bb6b60c22ce.zip |
Merge branch 'master' of ssh://sources.redhat.com/git/systemtap
Diffstat (limited to 'runtime')
-rw-r--r-- | runtime/ChangeLog | 6 | ||||
-rw-r--r-- | runtime/print_new.c | 6 | ||||
-rw-r--r-- | runtime/staprun/ChangeLog | 6 | ||||
-rw-r--r-- | runtime/staprun/staprun_funcs.c | 2 | ||||
-rw-r--r-- | runtime/transport/ChangeLog | 6 | ||||
-rw-r--r-- | runtime/transport/utt.c | 94 | ||||
-rw-r--r-- | runtime/transport/utt.h | 36 | ||||
-rw-r--r-- | runtime/uprobes/uprobes_i386.c | 5 | ||||
-rw-r--r-- | runtime/uprobes/uprobes_x86.c | 11 | ||||
-rw-r--r-- | runtime/uprobes/uprobes_x86_64.c | 11 |
10 files changed, 167 insertions, 16 deletions
diff --git a/runtime/ChangeLog b/runtime/ChangeLog index 6ad7e51f..e5594783 100644 --- a/runtime/ChangeLog +++ b/runtime/ChangeLog @@ -1,3 +1,9 @@ +2008-09-17 Frank Ch. Eigler <fche@elastic.org> + + PR 6487, 6504. + From Masami Hiramatsu <mhiramat@redhat.com> + * print_new.c (stp_print_flush): Use new utt_reserve(). + 2008-09-12 Masami Hiramatsu <mhiramat@redhat.com> BZ 6028 diff --git a/runtime/print_new.c b/runtime/print_new.c index 07af2e33..4136ecbe 100644 --- a/runtime/print_new.c +++ b/runtime/print_new.c @@ -34,13 +34,13 @@ void EXPORT_FN(stp_print_flush) (_stp_pbuf *pb) #ifdef STP_BULKMODE { #ifdef NO_PERCPU_HEADERS - void *buf = relay_reserve(_stp_utt->rchan, len); + void *buf = utt_reserve(_stp_utt, len); if (likely(buf)) memcpy(buf, pb->buf, len); else atomic_inc (&_stp_transport_failures); #else - void *buf = relay_reserve(_stp_utt->rchan, + void *buf = utt_reserve(_stp_utt, sizeof(struct _stp_trace) + len); if (likely(buf)) { struct _stp_trace t = { .sequence = _stp_seq_inc(), @@ -56,7 +56,7 @@ void EXPORT_FN(stp_print_flush) (_stp_pbuf *pb) void *buf; unsigned long flags; spin_lock_irqsave(&_stp_print_lock, flags); - buf = relay_reserve(_stp_utt->rchan, len); + buf = utt_reserve(_stp_utt, len); if (likely(buf)) memcpy(buf, pb->buf, len); else diff --git a/runtime/staprun/ChangeLog b/runtime/staprun/ChangeLog index 21e02e47..c6d75106 100644 --- a/runtime/staprun/ChangeLog +++ b/runtime/staprun/ChangeLog @@ -1,3 +1,9 @@ +2008-09-18 David Smith <dsmith@redhat.com> + + PR 6903. + * staprun_funcs.c (check_permissions): Instead of checking the + effective uid, check the real uid for root permissions. + 2008-09-06 Frank Ch. Eigler <fche@elastic.org> * mainloop.c (start_cmd): Rewrite to use wordexp/execvp/ptrace. diff --git a/runtime/staprun/staprun_funcs.c b/runtime/staprun/staprun_funcs.c index 8fa95e45..5e7fa102 100644 --- a/runtime/staprun/staprun_funcs.c +++ b/runtime/staprun/staprun_funcs.c @@ -307,7 +307,7 @@ int check_permissions(void) int path_check = 0; /* If we're root, we can do anything. */ - if (geteuid() == 0) + if (getuid() == 0) return 1; /* Lookup the gid for group "stapdev" */ diff --git a/runtime/transport/ChangeLog b/runtime/transport/ChangeLog index 693f06d1..42c6fc2a 100644 --- a/runtime/transport/ChangeLog +++ b/runtime/transport/ChangeLog @@ -1,3 +1,9 @@ +2008-09-17 Frank Ch. Eigler <fche@elastic.org> + + PR 6487, 6504. + From Masami Hiramatsu <mhiramat@redhat.com> + * utt.c (utt_switch_subbof, _utt_wakeup*, utt_reserve): New. + 2008-07-17 Frank Ch. Eigler <fche@elastic.org> * symbols.c (_stp_do_relocation): Adapt to stp_module decl changes. diff --git a/runtime/transport/utt.c b/runtime/transport/utt.c index 182c1178..b8281bb4 100644 --- a/runtime/transport/utt.c +++ b/runtime/transport/utt.c @@ -31,6 +31,96 @@ static int utt_overwrite_flag = 0; +/* + * utt_switch_subbuf - switch to a new sub-buffer + * + * Most of this function is deadcopy of relay_switch_subbuf. + */ +size_t utt_switch_subbuf(struct utt_trace *utt, struct rchan_buf *buf, + size_t length) +{ + void *old, *new; + size_t old_subbuf, new_subbuf; + + if (unlikely(buf == NULL)) + return 0; + + if (unlikely(length > buf->chan->subbuf_size)) + goto toobig; + + if (buf->offset != buf->chan->subbuf_size + 1) { + buf->prev_padding = buf->chan->subbuf_size - buf->offset; + old_subbuf = buf->subbufs_produced % buf->chan->n_subbufs; + buf->padding[old_subbuf] = buf->prev_padding; + buf->subbufs_produced++; + buf->dentry->d_inode->i_size += buf->chan->subbuf_size - + buf->padding[old_subbuf]; + smp_mb(); + if (waitqueue_active(&buf->read_wait)) + /* + * Calling wake_up_interruptible() and __mod_timer() + * from here will deadlock if we happen to be logging + * from the scheduler and timer (trying to re-grab + * rq->lock/timer->base->lock), so just set a flag. + */ + atomic_set(&utt->wakeup, 1); + } + + old = buf->data; + new_subbuf = buf->subbufs_produced % buf->chan->n_subbufs; + new = buf->start + new_subbuf * buf->chan->subbuf_size; + buf->offset = 0; + if (!buf->chan->cb->subbuf_start(buf, new, old, buf->prev_padding)) { + buf->offset = buf->chan->subbuf_size + 1; + return 0; + } + buf->data = new; + buf->padding[new_subbuf] = 0; + + if (unlikely(length + buf->offset > buf->chan->subbuf_size)) + goto toobig; + + return length; + +toobig: + buf->chan->last_toobig = length; + return 0; +} + +static void __utt_wakeup_readers(struct rchan_buf *buf) +{ + if (buf && waitqueue_active(&buf->read_wait) && + buf->subbufs_produced != buf->subbufs_consumed) + wake_up_interruptible(&buf->read_wait); +} + +static void __utt_wakeup_timer(unsigned long val) +{ + struct utt_trace *utt = (struct utt_trace *)val; + int i; + + if (atomic_read(&utt->wakeup)) { + atomic_set(&utt->wakeup, 0); + if (utt->is_global) + __utt_wakeup_readers(utt->rchan->buf[0]); + else + for_each_possible_cpu(i) + __utt_wakeup_readers(utt->rchan->buf[i]); + } + + mod_timer(&utt->timer, jiffies + UTT_TIMER_INTERVAL); +} + +static void __utt_timer_init(struct utt_trace * utt) +{ + atomic_set(&utt->wakeup, 0); + init_timer(&utt->timer); + utt->timer.expires = jiffies + UTT_TIMER_INTERVAL; + utt->timer.function = __utt_wakeup_timer; + utt->timer.data = (unsigned long)utt; + add_timer(&utt->timer); +} + void utt_set_overwrite(int overwrite) { utt_overwrite_flag = overwrite; @@ -241,6 +331,8 @@ struct utt_trace *utt_trace_setup(struct utt_trace_setup *utts) goto err; utt->rchan->private_data = utt; + utt->is_global = utts->is_global; + utt->trace_state = Utt_trace_setup; utts->err = 0; @@ -274,6 +366,7 @@ int utt_trace_startstop(struct utt_trace *utt, int start, utt->trace_state == Utt_trace_stopped) { if (trace_seq) (*trace_seq)++; + __utt_timer_init(utt); smp_mb(); utt->trace_state = Utt_trace_running; ret = 0; @@ -281,6 +374,7 @@ int utt_trace_startstop(struct utt_trace *utt, int start, } else { if (utt->trace_state == Utt_trace_running) { utt->trace_state = Utt_trace_stopped; + del_timer_sync(&utt->timer); relay_flush(utt->rchan); ret = 0; } diff --git a/runtime/transport/utt.h b/runtime/transport/utt.h index b2c9fa9f..fd704009 100644 --- a/runtime/transport/utt.h +++ b/runtime/transport/utt.h @@ -15,11 +15,18 @@ struct utt_trace { atomic_t dropped; struct dentry *utt_tree_root; /* systemtap */ void *private_data; + atomic_t wakeup; + struct timer_list timer; + int is_global; }; #define UTT_TRACE_ROOT_NAME_SIZE 64 /* Largest string for a root dir identifier */ #define UTT_TRACE_NAME_SIZE 64 /* Largest string for a trace identifier */ +#ifndef UTT_TIMER_INTERVAL +#define UTT_TIMER_INTERVAL ((HZ + 99) / 100) /* Wakeup timer interval in jiffies (default 10 ms)*/ +#endif + /* * User setup structure */ @@ -39,4 +46,33 @@ extern int utt_trace_startstop(struct utt_trace *utt, int start, extern void utt_trace_cleanup(struct utt_trace *utt); extern int utt_trace_remove(struct utt_trace *utt); +#ifndef STP_OLD_TRANSPORT +extern size_t utt_switch_subbuf(struct utt_trace *utt, struct rchan_buf *buf, + size_t length); +/** + * utt_reserve - reserve slot in channel buffer + * @utt: utt channel + * @length: number of bytes to reserve + * + * Returns pointer to reserved slot, NULL if full. + * + * This function is utt_switch_subbuf version of relay_reserve. + */ +static inline void *utt_reserve(struct utt_trace *utt, size_t length) +{ + void *reserved; + struct rchan_buf *buf = utt->rchan->buf[smp_processor_id()]; + + if (unlikely(buf->offset + length > buf->chan->subbuf_size)) { + length = utt_switch_subbuf(utt, buf, length); + if (!length) + return NULL; + } + reserved = buf->data + buf->offset; + buf->offset += length; + + return reserved; +} +#endif + #endif diff --git a/runtime/uprobes/uprobes_i386.c b/runtime/uprobes/uprobes_i386.c index 5fe7d781..51b06f79 100644 --- a/runtime/uprobes/uprobes_i386.c +++ b/runtime/uprobes/uprobes_i386.c @@ -41,7 +41,7 @@ W(0x30, 1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1), /* 30 */ W(0x40, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1)| /* 40 */ W(0x50, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1), /* 50 */ - W(0x60, 1,1,1,0,0,0,0,0,1,1,1,1,0,0,0,0)| /* 60 */ + W(0x60, 1,1,1,0,1,1,0,0,1,1,1,1,0,0,0,0)| /* 60 */ W(0x70, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1), /* 70 */ W(0x80, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1)| /* 80 */ W(0x90, 1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1), /* 90 */ @@ -111,7 +111,8 @@ * * others -- Do we need to support these? * 07, 17, 1f - pop es, pop ss, pop ds - * 26, 2e, 36, 3e, 64, 65 - es:, cs:, ss:, ds:, fs:, gs: segment prefixes + * 26, 2e, 36, 3e, - es:, cs:, ss:, ds: segment prefixes -- + * but 64 and 65 (fs: and gs:) seems to be used, so we support them. * 67 - addr16 prefix * 9b - wait/fwait * ce - into diff --git a/runtime/uprobes/uprobes_x86.c b/runtime/uprobes/uprobes_x86.c index ebb10d4e..05d2a978 100644 --- a/runtime/uprobes/uprobes_x86.c +++ b/runtime/uprobes/uprobes_x86.c @@ -43,7 +43,7 @@ static const unsigned long long good_insns_64[256 / 64] = { W(0x30, 1,1,1,1,1,1,0,0,1,1,1,1,1,1,0,0), /* 30 */ W(0x40, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)| /* 40 */ W(0x50, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1)| /* 50 */ - W(0x60, 0,0,0,1,0,0,0,0,1,1,1,1,0,0,0,0)| /* 60 */ + W(0x60, 0,0,0,1,1,1,0,0,1,1,1,1,0,0,0,0)| /* 60 */ W(0x70, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1), /* 70 */ W(0x80, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1)| /* 80 */ W(0x90, 1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1)| /* 90 */ @@ -68,7 +68,7 @@ static const unsigned long long good_insns_32[256 / 64] = { W(0x30, 1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1), /* 30 */ W(0x40, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1)| /* 40 */ W(0x50, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1)| /* 50 */ - W(0x60, 1,1,1,0,0,0,0,0,1,1,1,1,0,0,0,0)| /* 60 */ + W(0x60, 1,1,1,0,1,1,0,0,1,1,1,1,0,0,0,0)| /* 60 */ W(0x70, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1), /* 70 */ W(0x80, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1)| /* 80 */ W(0x90, 1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1)| /* 90 */ @@ -138,7 +138,8 @@ static const unsigned long long good_2byte_insns[256 / 64] = { * others -- Do we need to support these? * 0f - (floating-point?) prefetch instructions * 07, 17, 1f - pop es, pop ss, pop ds - * 26, 2e, 36, 3e, 64, 65 - es:, cs:, ss:, ds:, fs:, gs: segment prefixes + * 26, 2e, 36, 3e - es:, cs:, ss:, ds: segment prefixes -- + * but 64 and 65 (fs: and gs:) seems to be used, so we support them. * 67 - addr16 prefix * 9b - wait/fwait * ce - into @@ -165,10 +166,10 @@ static inline int check_legacy_prefix(u8 byte) case 0x2e: case 0x36: case 0x3e: - case 0x64: - case 0x65: case 0xf0: return -1; + case 0x64: + case 0x65: case 0x66: case 0x67: case 0xf2: diff --git a/runtime/uprobes/uprobes_x86_64.c b/runtime/uprobes/uprobes_x86_64.c index 78969248..a681cab5 100644 --- a/runtime/uprobes/uprobes_x86_64.c +++ b/runtime/uprobes/uprobes_x86_64.c @@ -43,7 +43,7 @@ static const unsigned long good_insns_64[256 / 64] = { W(0x30, 1,1,1,1,1,1,0,0,1,1,1,1,1,1,0,0), /* 30 */ W(0x40, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)| /* 40 */ W(0x50, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1)| /* 50 */ - W(0x60, 0,0,0,1,0,0,0,0,1,1,1,1,0,0,0,0)| /* 60 */ + W(0x60, 0,0,0,1,1,1,0,0,1,1,1,1,0,0,0,0)| /* 60 */ W(0x70, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1), /* 70 */ W(0x80, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1)| /* 80 */ W(0x90, 1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1)| /* 90 */ @@ -68,7 +68,7 @@ static const unsigned long good_insns_32[256 / 64] = { W(0x30, 1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1), /* 30 */ W(0x40, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1)| /* 40 */ W(0x50, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1)| /* 50 */ - W(0x60, 1,1,1,0,0,0,0,0,1,1,1,1,0,0,0,0)| /* 60 */ + W(0x60, 1,1,1,0,1,1,0,0,1,1,1,1,0,0,0,0)| /* 60 */ W(0x70, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1), /* 70 */ W(0x80, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1)| /* 80 */ W(0x90, 1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1)| /* 90 */ @@ -138,7 +138,8 @@ static const unsigned long good_2byte_insns[256 / 64] = { * others -- Do we need to support these? * 0f - (floating-point?) prefetch instructions * 07, 17, 1f - pop es, pop ss, pop ds - * 26, 2e, 36, 3e, 64, 65 - es:, cs:, ss:, ds:, fs:, gs: segment prefixes + * 26, 2e, 36, 3e - es:, cs:, ss:, ds: segment prefixes -- + * but 64 and 65 (fs: and gs:) seems to be used, so we support them. * 67 - addr16 prefix * 9b - wait/fwait * ce - into @@ -165,10 +166,10 @@ static inline int check_legacy_prefix(u8 byte) case 0x2e: case 0x36: case 0x3e: - case 0x64: - case 0x65: case 0xf0: return -1; + case 0x64: + case 0x65: case 0x66: case 0x67: case 0xf2: |