Change trace_seq_*() and get_unused_fd_flags() to support Linux 3.18 Signed-off-by: He Kuang <hekuang@xxxxxxxxxx> --- runtime/kp_events.c | 3 ++- runtime/kp_transport.c | 35 +++++++++++++++++++---------------- runtime/ktap.c | 2 +- runtime/ktap.h | 30 ++++++++++++++++++++++++++++++ runtime/lib_base.c | 4 ++-- 5 files changed, 54 insertions(+), 20 deletions(-) diff --git a/runtime/kp_events.c b/runtime/kp_events.c index a92a6e6..7d61a76 100644 --- a/runtime/kp_events.c +++ b/runtime/kp_events.c @@ -74,7 +74,8 @@ const char *kp_event_tostr(ktap_state_t *ks) if (ret != TRACE_TYPE_NO_CONSUME) { struct trace_seq *s = &iter->seq; - int len = s->len >= PAGE_SIZE ? PAGE_SIZE - 1 : s->len; + int len = trace_seq_used(s) >= PAGE_SIZE ? PAGE_SIZE - 1 : + trace_seq_used(s); s->buffer[len] = '\0'; return &s->buffer[0]; diff --git a/runtime/kp_transport.c b/runtime/kp_transport.c index 0a51fc3..6353308 100644 --- a/runtime/kp_transport.c +++ b/runtime/kp_transport.c @@ -64,19 +64,19 @@ ssize_t _trace_seq_to_user(struct trace_seq *s, char __user *ubuf, size_t cnt) if (!cnt) return 0; - if (s->len <= s->readpos) + if (trace_seq_used(s) <= TRACE_SEQ_READPOS(s)) return -EBUSY; - len = s->len - s->readpos; + len = trace_seq_used(s) - TRACE_SEQ_READPOS(s); if (cnt > len) cnt = len; - ret = copy_to_user(ubuf, s->buffer + s->readpos, cnt); + ret = copy_to_user(ubuf, s->buffer + TRACE_SEQ_READPOS(s), cnt); if (ret == cnt) return -EFAULT; cnt -= ret; - s->readpos += cnt; + TRACE_SEQ_READPOS(s) += cnt; return cnt; } @@ -87,13 +87,13 @@ int _trace_seq_puts(struct trace_seq *s, const char *str) if (s->full) return 0; - if (len > ((PAGE_SIZE - 1) - s->len)) { + if (len > ((PAGE_SIZE - 1) - TRACE_SEQ_LEN(s))) { s->full = 1; return 0; } - memcpy(s->buffer + s->len, str, len); - s->len += len; + memcpy(s->buffer + TRACE_SEQ_LEN(s), str, len); + TRACE_SEQ_LEN(s) += len; return len; } @@ -136,7 +136,8 @@ static int trace_print_timestamp(struct trace_iterator *iter) usec_rem = do_div(t, USEC_PER_SEC); secs = (unsigned long)t; - return trace_seq_printf(s, "%5lu.%06lu: ", secs, usec_rem); + trace_seq_printf(s, "%5lu.%06lu: ", secs, usec_rem); + return !trace_seq_has_overflowed(s); } /* todo: export kernel function ftrace_find_event in future, and make faster */ @@ -157,8 +158,8 @@ static enum print_line_t print_trace_fmt(struct trace_iterator *iter) int ret = ev->funcs->trace(iter, 0, ev); /* overwrite '\n' at the ending */ - iter->seq.buffer[iter->seq.len - 1] = '\0'; - iter->seq.len--; + iter->seq.buffer[TRACE_SEQ_LEN(&iter->seq) - 1] = '\0'; + TRACE_SEQ_LEN(&iter->seq)--; return ret; } @@ -186,7 +187,8 @@ static enum print_line_t print_trace_stack(struct trace_iterator *iter) break; sprint_symbol(str, p); - if (!trace_seq_printf(&iter->seq, " => %s\n", str)) + trace_seq_printf(&iter->seq, " => %s\n", str); + if (trace_seq_has_overflowed(&iter->seq)) return TRACE_TYPE_PARTIAL_LINE; } @@ -237,7 +239,8 @@ static enum print_line_t print_trace_line(struct trace_iterator *iter) char *str = (char *)(entry + 1); if (entry->type == TRACE_PRINT) { - if (!trace_seq_printf(&iter->seq, "%s", str)) + trace_seq_printf(&iter->seq, "%s", str); + if (trace_seq_has_overflowed(&iter->seq)) return TRACE_TYPE_PARTIAL_LINE; return TRACE_TYPE_HANDLED; @@ -398,18 +401,18 @@ waitagain: while (trace_find_next_entry_inc(iter) != NULL) { enum print_line_t ret; - int len = iter->seq.len; + int len = trace_seq_used(&iter->seq); ret = print_trace_line(iter); if (ret == TRACE_TYPE_PARTIAL_LINE) { /* don't print partial lines */ - iter->seq.len = len; + TRACE_SEQ_LEN(&iter->seq) = len; break; } if (ret != TRACE_TYPE_NO_CONSUME) trace_consume(iter); - if (iter->seq.len >= cnt) + if (TRACE_SEQ_LEN(&iter->seq) >= cnt) break; /* @@ -423,7 +426,7 @@ waitagain: /* Now copy what we have to the user */ sret = _trace_seq_to_user(&iter->seq, ubuf, cnt); - if (iter->seq.readpos >= iter->seq.len) + if (TRACE_SEQ_READPOS(&iter->seq) >= TRACE_SEQ_LEN(&iter->seq)) trace_seq_init(&iter->seq); /* diff --git a/runtime/ktap.c b/runtime/ktap.c index e5e18d7..01ecc6c 100644 --- a/runtime/ktap.c +++ b/runtime/ktap.c @@ -174,7 +174,7 @@ static long ktapvm_ioctl(struct file *file, unsigned int cmd, unsigned long arg) int new_fd, err; struct file *new_file; - new_fd = get_unused_fd(); + new_fd = get_unused_fd_flags(0); if (new_fd < 0) return new_fd; diff --git a/runtime/ktap.h b/runtime/ktap.h index 1897a33..cc54b0f 100644 --- a/runtime/ktap.h +++ b/runtime/ktap.h @@ -9,6 +9,36 @@ #define raw_cpu_ptr __this_cpu_ptr #endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 18, 0) +/** + * trace_seq_has_overflowed - return true if the trace_seq took too much + * @s: trace sequence descriptor + * + * Returns true if too much data was added to the trace_seq and it is + * now full and will not take anymore. + */ +#define TRACE_SEQ_BUF_LEFT(s) ((PAGE_SIZE - 1) - (s)->len) +static inline bool trace_seq_has_overflowed(struct trace_seq *s) +{ + unsigned int len = TRACE_SEQ_BUF_LEFT(s); + + return (s->full || !len); +} + +static inline int trace_seq_used(struct trace_seq *s) +{ + return s->len; +} +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 18, 0) +#define TRACE_SEQ_READPOS(s) ((s)->readpos) +#define TRACE_SEQ_LEN(s) ((s)->len) +#else +#define TRACE_SEQ_READPOS(s) ((s)->seq.readpos) +#define TRACE_SEQ_LEN(s) ((s)->seq.len) +#endif + /* for built-in library C function register */ typedef struct ktap_libfunc { const char *name; /* function name */ diff --git a/runtime/lib_base.c b/runtime/lib_base.c index c2f9e8b..8129159 100644 --- a/runtime/lib_base.c +++ b/runtime/lib_base.c @@ -75,8 +75,8 @@ static int kplib_printf(ktap_state_t *ks) if (kp_str_fmt(ks, seq)) goto out; - seq->buffer[seq->len] = '\0'; - kp_transport_write(ks, seq->buffer, seq->len + 1); + seq->buffer[trace_seq_used(seq)] = '\0'; + kp_transport_write(ks, seq->buffer, trace_seq_used(seq) + 1); out: preempt_enable_notrace(); -- 2.2.0.33.gc18b867