Merge branch 'tracing/urgent' into tracing/ftrace
authorIngo Molnar <mingo@elte.hu>
Tue, 7 Apr 2009 12:41:14 +0000 (14:41 +0200)
committerIngo Molnar <mingo@elte.hu>
Tue, 7 Apr 2009 12:41:17 +0000 (14:41 +0200)
1  2 
block/blk-core.c
include/linux/ftrace.h
include/linux/init_task.h
kernel/trace/trace.c
kernel/trace/trace.h
kernel/trace/trace_output.c

diff --combined block/blk-core.c
@@@ -132,6 -132,7 +132,7 @@@ void blk_rq_init(struct request_queue *
        INIT_HLIST_NODE(&rq->hash);
        RB_CLEAR_NODE(&rq->rb_node);
        rq->cmd = rq->__cmd;
+       rq->cmd_len = BLK_MAX_CDB;
        rq->tag = -1;
        rq->ref_count = 1;
  }
@@@ -484,11 -485,11 +485,11 @@@ static int blk_init_free_list(struct re
  {
        struct request_list *rl = &q->rq;
  
 -      rl->count[READ] = rl->count[WRITE] = 0;
 -      rl->starved[READ] = rl->starved[WRITE] = 0;
 +      rl->count[BLK_RW_SYNC] = rl->count[BLK_RW_ASYNC] = 0;
 +      rl->starved[BLK_RW_SYNC] = rl->starved[BLK_RW_ASYNC] = 0;
        rl->elvpriv = 0;
 -      init_waitqueue_head(&rl->wait[READ]);
 -      init_waitqueue_head(&rl->wait[WRITE]);
 +      init_waitqueue_head(&rl->wait[BLK_RW_SYNC]);
 +      init_waitqueue_head(&rl->wait[BLK_RW_ASYNC]);
  
        rl->rq_pool = mempool_create_node(BLKDEV_MIN_RQ, mempool_alloc_slab,
                                mempool_free_slab, request_cachep, q->node);
@@@ -603,10 -604,13 +604,10 @@@ blk_init_queue_node(request_fn_proc *rf
        q->queue_flags          = QUEUE_FLAG_DEFAULT;
        q->queue_lock           = lock;
  
 -      blk_queue_segment_boundary(q, BLK_SEG_BOUNDARY_MASK);
 -
 +      /*
 +       * This also sets hw/phys segments, boundary and size
 +       */
        blk_queue_make_request(q, __make_request);
 -      blk_queue_max_segment_size(q, MAX_SEGMENT_SIZE);
 -
 -      blk_queue_max_hw_segments(q, MAX_HW_SEGMENTS);
 -      blk_queue_max_phys_segments(q, MAX_PHYS_SEGMENTS);
  
        q->sg_reserved_size = INT_MAX;
  
@@@ -699,18 -703,18 +700,18 @@@ static void ioc_set_batching(struct req
        ioc->last_waited = jiffies;
  }
  
 -static void __freed_request(struct request_queue *q, int rw)
 +static void __freed_request(struct request_queue *q, int sync)
  {
        struct request_list *rl = &q->rq;
  
 -      if (rl->count[rw] < queue_congestion_off_threshold(q))
 -              blk_clear_queue_congested(q, rw);
 +      if (rl->count[sync] < queue_congestion_off_threshold(q))
 +              blk_clear_queue_congested(q, sync);
  
 -      if (rl->count[rw] + 1 <= q->nr_requests) {
 -              if (waitqueue_active(&rl->wait[rw]))
 -                      wake_up(&rl->wait[rw]);
 +      if (rl->count[sync] + 1 <= q->nr_requests) {
 +              if (waitqueue_active(&rl->wait[sync]))
 +                      wake_up(&rl->wait[sync]);
  
 -              blk_clear_queue_full(q, rw);
 +              blk_clear_queue_full(q, sync);
        }
  }
  
   * A request has just been released.  Account for it, update the full and
   * congestion status, wake up any waiters.   Called under q->queue_lock.
   */
 -static void freed_request(struct request_queue *q, int rw, int priv)
 +static void freed_request(struct request_queue *q, int sync, int priv)
  {
        struct request_list *rl = &q->rq;
  
 -      rl->count[rw]--;
 +      rl->count[sync]--;
        if (priv)
                rl->elvpriv--;
  
 -      __freed_request(q, rw);
 +      __freed_request(q, sync);
  
 -      if (unlikely(rl->starved[rw ^ 1]))
 -              __freed_request(q, rw ^ 1);
 +      if (unlikely(rl->starved[sync ^ 1]))
 +              __freed_request(q, sync ^ 1);
  }
  
 -#define blkdev_free_rq(list) list_entry((list)->next, struct request, queuelist)
  /*
   * Get a free request, queue_lock must be held.
   * Returns NULL on failure, with queue_lock held.
@@@ -743,15 -748,15 +744,15 @@@ static struct request *get_request(stru
        struct request *rq = NULL;
        struct request_list *rl = &q->rq;
        struct io_context *ioc = NULL;
 -      const int rw = rw_flags & 0x01;
 +      const bool is_sync = rw_is_sync(rw_flags) != 0;
        int may_queue, priv;
  
        may_queue = elv_may_queue(q, rw_flags);
        if (may_queue == ELV_MQUEUE_NO)
                goto rq_starved;
  
 -      if (rl->count[rw]+1 >= queue_congestion_on_threshold(q)) {
 -              if (rl->count[rw]+1 >= q->nr_requests) {
 +      if (rl->count[is_sync]+1 >= queue_congestion_on_threshold(q)) {
 +              if (rl->count[is_sync]+1 >= q->nr_requests) {
                        ioc = current_io_context(GFP_ATOMIC, q->node);
                        /*
                         * The queue will fill after this allocation, so set
                         * This process will be allowed to complete a batch of
                         * requests, others will be blocked.
                         */
 -                      if (!blk_queue_full(q, rw)) {
 +                      if (!blk_queue_full(q, is_sync)) {
                                ioc_set_batching(q, ioc);
 -                              blk_set_queue_full(q, rw);
 +                              blk_set_queue_full(q, is_sync);
                        } else {
                                if (may_queue != ELV_MQUEUE_MUST
                                                && !ioc_batching(q, ioc)) {
                                }
                        }
                }
 -              blk_set_queue_congested(q, rw);
 +              blk_set_queue_congested(q, is_sync);
        }
  
        /*
         * limit of requests, otherwise we could have thousands of requests
         * allocated with any setting of ->nr_requests
         */
 -      if (rl->count[rw] >= (3 * q->nr_requests / 2))
 +      if (rl->count[is_sync] >= (3 * q->nr_requests / 2))
                goto out;
  
 -      rl->count[rw]++;
 -      rl->starved[rw] = 0;
 +      rl->count[is_sync]++;
 +      rl->starved[is_sync] = 0;
  
        priv = !test_bit(QUEUE_FLAG_ELVSWITCH, &q->queue_flags);
        if (priv)
                 * wait queue, but this is pretty rare.
                 */
                spin_lock_irq(q->queue_lock);
 -              freed_request(q, rw, priv);
 +              freed_request(q, is_sync, priv);
  
                /*
                 * in the very unlikely event that allocation failed and no
                 * rq mempool into READ and WRITE
                 */
  rq_starved:
 -              if (unlikely(rl->count[rw] == 0))
 -                      rl->starved[rw] = 1;
 +              if (unlikely(rl->count[is_sync] == 0))
 +                      rl->starved[is_sync] = 1;
  
                goto out;
        }
        if (ioc_batching(q, ioc))
                ioc->nr_batch_requests--;
  
 -      trace_block_getrq(q, bio, rw);
 +      trace_block_getrq(q, bio, rw_flags & 1);
  out:
        return rq;
  }
  static struct request *get_request_wait(struct request_queue *q, int rw_flags,
                                        struct bio *bio)
  {
 -      const int rw = rw_flags & 0x01;
 +      const bool is_sync = rw_is_sync(rw_flags) != 0;
        struct request *rq;
  
        rq = get_request(q, rw_flags, bio, GFP_NOIO);
                struct io_context *ioc;
                struct request_list *rl = &q->rq;
  
 -              prepare_to_wait_exclusive(&rl->wait[rw], &wait,
 +              prepare_to_wait_exclusive(&rl->wait[is_sync], &wait,
                                TASK_UNINTERRUPTIBLE);
  
 -              trace_block_sleeprq(q, bio, rw);
 +              trace_block_sleeprq(q, bio, rw_flags & 1);
  
                __generic_unplug_device(q);
                spin_unlock_irq(q->queue_lock);
                ioc_set_batching(q, ioc);
  
                spin_lock_irq(q->queue_lock);
 -              finish_wait(&rl->wait[rw], &wait);
 +              finish_wait(&rl->wait[is_sync], &wait);
  
                rq = get_request(q, rw_flags, bio, GFP_NOIO);
        };
@@@ -1062,22 -1067,19 +1063,22 @@@ void __blk_put_request(struct request_q
  
        elv_completed_request(q, req);
  
 +      /* this is a bio leak */
 +      WARN_ON(req->bio != NULL);
 +
        /*
         * Request may not have originated from ll_rw_blk. if not,
         * it didn't come out of our reserved rq pools
         */
        if (req->cmd_flags & REQ_ALLOCED) {
 -              int rw = rq_data_dir(req);
 +              int is_sync = rq_is_sync(req) != 0;
                int priv = req->cmd_flags & REQ_ELVPRIV;
  
                BUG_ON(!list_empty(&req->queuelist));
                BUG_ON(!hlist_unhashed(&req->hash));
  
                blk_free_request(q, req);
 -              freed_request(q, rw, priv);
 +              freed_request(q, is_sync, priv);
        }
  }
  EXPORT_SYMBOL_GPL(__blk_put_request);
@@@ -1128,8 -1130,6 +1129,8 @@@ void init_request_from_bio(struct reque
                req->cmd_flags |= REQ_UNPLUG;
        if (bio_rw_meta(bio))
                req->cmd_flags |= REQ_RW_META;
 +      if (bio_noidle(bio))
 +              req->cmd_flags |= REQ_NOIDLE;
  
        req->errors = 0;
        req->hard_sector = req->sector = bio->bi_sector;
        blk_rq_bio_prep(req->q, req, bio);
  }
  
 +/*
 + * Only disabling plugging for non-rotational devices if it does tagging
 + * as well, otherwise we do need the proper merging
 + */
 +static inline bool queue_should_plug(struct request_queue *q)
 +{
 +      return !(blk_queue_nonrot(q) && blk_queue_tagged(q));
 +}
 +
  static int __make_request(struct request_queue *q, struct bio *bio)
  {
        struct request *req;
@@@ -1253,11 -1244,11 +1254,11 @@@ get_rq
        if (test_bit(QUEUE_FLAG_SAME_COMP, &q->queue_flags) ||
            bio_flagged(bio, BIO_CPU_AFFINE))
                req->cpu = blk_cpu_to_group(smp_processor_id());
 -      if (!blk_queue_nonrot(q) && elv_queue_empty(q))
 +      if (queue_should_plug(q) && elv_queue_empty(q))
                blk_plug_device(q);
        add_request(q, req);
  out:
 -      if (unplug || blk_queue_nonrot(q))
 +      if (unplug || !queue_should_plug(q))
                __generic_unplug_device(q);
        spin_unlock_irq(q->queue_lock);
        return 0;
diff --combined include/linux/ftrace.h
@@@ -356,6 -356,9 +356,9 @@@ struct ftrace_graph_ret 
  
  #ifdef CONFIG_FUNCTION_GRAPH_TRACER
  
+ /* for init task */
+ #define INIT_FTRACE_GRAPH             .ret_stack = NULL
  /*
   * Stack of return addresses for functions
   * of a thread.
@@@ -365,7 -368,6 +368,7 @@@ struct ftrace_ret_stack 
        unsigned long ret;
        unsigned long func;
        unsigned long long calltime;
 +      unsigned long long subtime;
  };
  
  /*
@@@ -377,6 -379,8 +380,6 @@@ extern void return_to_handler(void)
  
  extern int
  ftrace_push_return_trace(unsigned long ret, unsigned long func, int *depth);
 -extern void
 -ftrace_pop_return_trace(struct ftrace_graph_ret *trace, unsigned long *ret);
  
  /*
   * Sometimes we don't want to trace a function with the function
@@@ -429,10 -433,11 +432,11 @@@ static inline void unpause_graph_tracin
  {
        atomic_dec(&current->tracing_graph_pause);
  }
- #else
+ #else /* !CONFIG_FUNCTION_GRAPH_TRACER */
  
  #define __notrace_funcgraph
  #define __irq_entry
+ #define INIT_FTRACE_GRAPH
  
  static inline void ftrace_graph_init_task(struct task_struct *t) { }
  static inline void ftrace_graph_exit_task(struct task_struct *t) { }
@@@ -444,7 -449,7 +448,7 @@@ static inline int task_curr_ret_stack(s
  
  static inline void pause_graph_tracing(void) { }
  static inline void unpause_graph_tracing(void) { }
- #endif
+ #endif /* CONFIG_FUNCTION_GRAPH_TRACER */
  
  #ifdef CONFIG_TRACING
  #include <linux/sched.h>
@@@ -5,6 -5,7 +5,7 @@@
  #include <linux/irqflags.h>
  #include <linux/utsname.h>
  #include <linux/lockdep.h>
+ #include <linux/ftrace.h>
  #include <linux/ipc.h>
  #include <linux/pid_namespace.h>
  #include <linux/user_namespace.h>
@@@ -147,7 -148,6 +148,7 @@@ extern struct cred init_cred
                .nr_cpus_allowed = NR_CPUS,                             \
        },                                                              \
        .tasks          = LIST_HEAD_INIT(tsk.tasks),                    \
 +      .pushable_tasks = PLIST_NODE_INIT(tsk.pushable_tasks, MAX_PRIO), \
        .ptraced        = LIST_HEAD_INIT(tsk.ptraced),                  \
        .ptrace_entry   = LIST_HEAD_INIT(tsk.ptrace_entry),             \
        .real_parent    = &tsk,                                         \
        INIT_IDS                                                        \
        INIT_TRACE_IRQFLAGS                                             \
        INIT_LOCKDEP                                                    \
+       INIT_FTRACE_GRAPH                                               \
  }
  
  
diff --combined kernel/trace/trace.c
@@@ -30,6 -30,7 +30,7 @@@
  #include <linux/percpu.h>
  #include <linux/splice.h>
  #include <linux/kdebug.h>
+ #include <linux/string.h>
  #include <linux/ctype.h>
  #include <linux/init.h>
  #include <linux/poll.h>
@@@ -147,8 -148,7 +148,7 @@@ static int __init set_ftrace_dump_on_oo
  }
  __setup("ftrace_dump_on_oops", set_ftrace_dump_on_oops);
  
- long
- ns2usecs(cycle_t nsec)
+ unsigned long long ns2usecs(cycle_t nsec)
  {
        nsec += 500;
        do_div(nsec, 1000);
@@@ -255,8 -255,7 +255,8 @@@ static DECLARE_WAIT_QUEUE_HEAD(trace_wa
  
  /* trace_flags holds trace_options default values */
  unsigned long trace_flags = TRACE_ITER_PRINT_PARENT | TRACE_ITER_PRINTK |
 -      TRACE_ITER_ANNOTATE | TRACE_ITER_CONTEXT_INFO | TRACE_ITER_SLEEP_TIME;
 +      TRACE_ITER_ANNOTATE | TRACE_ITER_CONTEXT_INFO | TRACE_ITER_SLEEP_TIME |
 +      TRACE_ITER_GRAPH_TIME;
  
  /**
   * trace_wake_up - wake up tasks waiting for trace input
@@@ -318,7 -317,6 +318,7 @@@ static const char *trace_options[] = 
        "latency-format",
        "global-clock",
        "sleep-time",
 +      "graph-time",
        NULL
  };
  
@@@ -404,6 -402,17 +404,6 @@@ static ssize_t trace_seq_to_buffer(stru
        return cnt;
  }
  
 -static void
 -trace_print_seq(struct seq_file *m, struct trace_seq *s)
 -{
 -      int len = s->len >= PAGE_SIZE ? PAGE_SIZE - 1 : s->len;
 -
 -      s->buffer[len] = 0;
 -      seq_puts(m, s->buffer);
 -
 -      trace_seq_init(s);
 -}
 -
  /**
   * update_max_tr - snapshot all trace buffers from global_trace to max_tr
   * @tr: tracer
@@@ -1623,7 -1632,11 +1623,11 @@@ static void test_cpu_buff_start(struct 
                return;
  
        cpumask_set_cpu(iter->cpu, iter->started);
-       trace_seq_printf(s, "##### CPU %u buffer started ####\n", iter->cpu);
+       /* Don't print started cpu buffer for the first entry of the trace */
+       if (iter->idx > 1)
+               trace_seq_printf(s, "##### CPU %u buffer started ####\n",
+                               iter->cpu);
  }
  
  static enum print_line_t print_trace_fmt(struct trace_iterator *iter)
@@@ -1858,6 -1871,11 +1862,11 @@@ __tracing_open(struct inode *inode, str
        if (current_trace)
                *iter->trace = *current_trace;
  
+       if (!alloc_cpumask_var(&iter->started, GFP_KERNEL))
+               goto fail;
+       cpumask_clear(iter->started);
        if (current_trace && current_trace->print_max)
                iter->tr = &max_tr;
        else
                if (iter->buffer_iter[cpu])
                        ring_buffer_read_finish(iter->buffer_iter[cpu]);
        }
+       free_cpumask_var(iter->started);
   fail:
        mutex_unlock(&trace_types_lock);
        kfree(iter->trace);
@@@ -1951,6 -1970,7 +1961,7 @@@ static int tracing_release(struct inod
  
        seq_release(inode, file);
        mutex_destroy(&iter->mutex);
+       free_cpumask_var(iter->started);
        kfree(iter->trace);
        kfree(iter);
        return 0;
@@@ -2349,9 -2369,9 +2360,9 @@@ static const char readme_msg[] 
        "# mkdir /debug\n"
        "# mount -t debugfs nodev /debug\n\n"
        "# cat /debug/tracing/available_tracers\n"
-       "wakeup preemptirqsoff preemptoff irqsoff ftrace sched_switch none\n\n"
+       "wakeup preemptirqsoff preemptoff irqsoff function sched_switch nop\n\n"
        "# cat /debug/tracing/current_tracer\n"
-       "none\n"
+       "nop\n"
        "# echo sched_switch > /debug/tracing/current_tracer\n"
        "# cat /debug/tracing/current_tracer\n"
        "sched_switch\n"
diff --combined kernel/trace/trace.h
@@@ -182,12 -182,6 +182,12 @@@ struct trace_power 
        struct power_trace      state_data;
  };
  
 +enum kmemtrace_type_id {
 +      KMEMTRACE_TYPE_KMALLOC = 0,     /* kmalloc() or kfree(). */
 +      KMEMTRACE_TYPE_CACHE,           /* kmem_cache_*(). */
 +      KMEMTRACE_TYPE_PAGES,           /* __get_free_pages() and friends. */
 +};
 +
  struct kmemtrace_alloc_entry {
        struct trace_entry      ent;
        enum kmemtrace_type_id type_id;
@@@ -602,7 -596,7 +602,7 @@@ extern int trace_selftest_startup_branc
  #endif /* CONFIG_FTRACE_STARTUP_TEST */
  
  extern void *head_page(struct trace_array_cpu *data);
- extern long ns2usecs(cycle_t nsec);
+ extern unsigned long long ns2usecs(cycle_t nsec);
  extern int
  trace_vbprintk(unsigned long ip, const char *fmt, va_list args);
  extern int
@@@ -613,8 -607,6 +613,8 @@@ extern unsigned long trace_flags
  /* Standard output formatting function used for function return traces */
  #ifdef CONFIG_FUNCTION_GRAPH_TRACER
  extern enum print_line_t print_graph_function(struct trace_iterator *iter);
 +extern enum print_line_t
 +trace_print_graph_duration(unsigned long long duration, struct trace_seq *s);
  
  #ifdef CONFIG_DYNAMIC_FTRACE
  /* TODO: make this variable */
@@@ -646,6 -638,7 +646,6 @@@ static inline int ftrace_graph_addr(uns
        return 1;
  }
  #endif /* CONFIG_DYNAMIC_FTRACE */
 -
  #else /* CONFIG_FUNCTION_GRAPH_TRACER */
  static inline enum print_line_t
  print_graph_function(struct trace_iterator *iter)
@@@ -693,7 -686,6 +693,7 @@@ enum trace_iterator_flags 
        TRACE_ITER_LATENCY_FMT          = 0x40000,
        TRACE_ITER_GLOBAL_CLK           = 0x80000,
        TRACE_ITER_SLEEP_TIME           = 0x100000,
 +      TRACE_ITER_GRAPH_TIME           = 0x200000,
  };
  
  /*
@@@ -19,16 -19,6 +19,16 @@@ static struct hlist_head event_hash[EVE
  
  static int next_event_type = __TRACE_LAST_TYPE + 1;
  
 +void trace_print_seq(struct seq_file *m, struct trace_seq *s)
 +{
 +      int len = s->len >= PAGE_SIZE ? PAGE_SIZE - 1 : s->len;
 +
 +      s->buffer[len] = 0;
 +      seq_puts(m, s->buffer);
 +
 +      trace_seq_init(s);
 +}
 +
  enum print_line_t trace_print_bprintk_msg_only(struct trace_iterator *iter)
  {
        struct trace_seq *s = &iter->seq;
@@@ -433,7 -423,7 +433,7 @@@ int trace_print_lat_context(struct trac
  
                trace_find_cmdline(entry->pid, comm);
  
-               ret = trace_seq_printf(s, "%16s %5d %3d %d %08x %08lx [%08lx]"
+               ret = trace_seq_printf(s, "%16s %5d %3d %d %08x %08lx [%08llx]"
                                       " %ld.%03ldms (+%ld.%03ldms): ", comm,
                                       entry->pid, iter->cpu, entry->flags,
                                       entry->preempt_count, iter->idx,