struct task_struct;
 extern void release_thread(struct task_struct *);
 
-unsigned long get_wchan(struct task_struct *p);
+unsigned long __get_wchan(struct task_struct *p);
 
 #define KSTK_EIP(tsk) (task_pt_regs(tsk)->pc)
 
 
 }
 
 unsigned long
-get_wchan(struct task_struct *p)
+__get_wchan(struct task_struct *p)
 {
        unsigned long schedule_frame;
        unsigned long pc;
-       if (!p || p == current || task_is_running(p))
-               return 0;
+
        /*
         * This one depends on the frame size of schedule().  Do a
         * "disass schedule" in gdb to find the frame size.  Also, the
 
 extern void start_thread(struct pt_regs * regs, unsigned long pc,
                         unsigned long usp);
 
-extern unsigned int get_wchan(struct task_struct *p);
+extern unsigned int __get_wchan(struct task_struct *p);
 
 #endif /* !__ASSEMBLY__ */
 
 
  *      = specifics of data structs where trace is saved(CONFIG_STACKTRACE etc)
  *
  *  vineetg: March 2009
- *  -Implemented correct versions of thread_saved_pc() and get_wchan()
+ *  -Implemented correct versions of thread_saved_pc() and __get_wchan()
  *
  *  rajeshwarr: 2008
  *  -Initial implementation
  * Of course just returning schedule( ) would be pointless so unwind until
  * the function is not in schedular code
  */
-unsigned int get_wchan(struct task_struct *tsk)
+unsigned int __get_wchan(struct task_struct *tsk)
 {
        return arc_unwind_core(tsk, NULL, __get_first_nonsched, NULL);
 }
 
 /* Free all resources held by a thread. */
 extern void release_thread(struct task_struct *);
 
-unsigned long get_wchan(struct task_struct *p);
+unsigned long __get_wchan(struct task_struct *p);
 
 #define task_pt_regs(p) \
        ((struct pt_regs *)(THREAD_START_SP + task_stack_page(p)) - 1)
 
        return 0;
 }
 
-unsigned long get_wchan(struct task_struct *p)
+unsigned long __get_wchan(struct task_struct *p)
 {
        struct stackframe frame;
        unsigned long stack_page;
        int count = 0;
-       if (!p || p == current || task_is_running(p))
-               return 0;
 
        frame.fp = thread_saved_fp(p);
        frame.sp = thread_saved_sp(p);
 
 /* Free all resources held by a thread. */
 extern void release_thread(struct task_struct *);
 
-unsigned long get_wchan(struct task_struct *p);
+unsigned long __get_wchan(struct task_struct *p);
 
 void update_sctlr_el1(u64 sctlr);
 
 
        return last;
 }
 
-unsigned long get_wchan(struct task_struct *p)
+unsigned long __get_wchan(struct task_struct *p)
 {
        struct stackframe frame;
        unsigned long stack_page, ret = 0;
        int count = 0;
-       if (!p || p == current || task_is_running(p))
-               return 0;
 
        stack_page = (unsigned long)try_get_task_stack(p);
        if (!stack_page)
 
 
 extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
 
-unsigned long get_wchan(struct task_struct *p);
+unsigned long __get_wchan(struct task_struct *p);
 
 #define KSTK_EIP(tsk)          (task_pt_regs(tsk)->pc)
 #define KSTK_ESP(tsk)          (task_pt_regs(tsk)->usp)
 
        return false;
 }
 
-unsigned long get_wchan(struct task_struct *task)
+unsigned long __get_wchan(struct task_struct *task)
 {
        unsigned long pc = 0;
 
-       if (likely(task && task != current && !task_is_running(task)))
-               walk_stackframe(task, NULL, save_wchan, &pc);
+       walk_stackframe(task, NULL, save_wchan, &pc);
        return pc;
 }
 
 
 {
 }
 
-unsigned long get_wchan(struct task_struct *p);
+unsigned long __get_wchan(struct task_struct *p);
 
 #define        KSTK_EIP(tsk)   \
        ({                       \
 
        return 0;
 }
 
-unsigned long get_wchan(struct task_struct *p)
+unsigned long __get_wchan(struct task_struct *p)
 {
        unsigned long fp, pc;
        unsigned long stack_page;
        int count = 0;
 
-       if (!p || p == current || task_is_running(p))
-               return 0;
-
        stack_page = (unsigned long)p;
        fp = ((struct pt_regs *)p->thread.ksp)->er6;
        do {
 
 extern void release_thread(struct task_struct *dead_task);
 
 /* Get wait channel for task P.  */
-extern unsigned long get_wchan(struct task_struct *p);
+extern unsigned long __get_wchan(struct task_struct *p);
 
 /*  The following stuff is pretty HEXAGON specific.  */
 
 
  * is an identification of the point at which the scheduler
  * was invoked by a blocked thread.
  */
-unsigned long get_wchan(struct task_struct *p)
+unsigned long __get_wchan(struct task_struct *p)
 {
        unsigned long fp, pc;
        unsigned long stack_page;
        int count = 0;
-       if (!p || p == current || task_is_running(p))
-               return 0;
 
        stack_page = (unsigned long)task_stack_page(p);
        fp = ((struct hexagon_switch_stack *)p->thread.switch_sp)->fp;
 
 #define release_thread(dead_task)
 
 /* Get wait channel for task P.  */
-extern unsigned long get_wchan (struct task_struct *p);
+extern unsigned long __get_wchan (struct task_struct *p);
 
 /* Return instruction pointer of blocked task TSK.  */
 #define KSTK_EIP(tsk)                                  \
 
 }
 
 unsigned long
-get_wchan (struct task_struct *p)
+__get_wchan (struct task_struct *p)
 {
        struct unw_frame_info info;
        unsigned long ip;
        int count = 0;
 
-       if (!p || p == current || task_is_running(p))
-               return 0;
-
        /*
         * Note: p may not be a blocked task (it could be current or
         * another process running on some other CPU.  Rather than
 
 {
 }
 
-unsigned long get_wchan(struct task_struct *p);
+unsigned long __get_wchan(struct task_struct *p);
 
 #define        KSTK_EIP(tsk)   \
     ({                 \
 
 }
 EXPORT_SYMBOL(dump_fpu);
 
-unsigned long get_wchan(struct task_struct *p)
+unsigned long __get_wchan(struct task_struct *p)
 {
        unsigned long fp, pc;
        unsigned long stack_page;
        int count = 0;
-       if (!p || p == current || task_is_running(p))
-               return 0;
 
        stack_page = (unsigned long)task_stack_page(p);
        fp = ((struct switch_stack *)p->thread.ksp)->a6;
 
 {
 }
 
-unsigned long get_wchan(struct task_struct *p);
+unsigned long __get_wchan(struct task_struct *p);
 
 /* The size allocated for kernel stacks. This _must_ be a power of two! */
 # define KERNEL_STACK_SIZE     0x2000
 
        return 0;
 }
 
-unsigned long get_wchan(struct task_struct *p)
+unsigned long __get_wchan(struct task_struct *p)
 {
 /* TBD (used by procfs) */
        return 0;
 
 {
 }
 
-unsigned long get_wchan(struct task_struct *p);
+unsigned long __get_wchan(struct task_struct *p);
 
 #define __KSTK_TOS(tsk) ((unsigned long)task_stack_page(tsk) + \
                         THREAD_SIZE - 32 - sizeof(struct pt_regs))
 
 
        /*
         * Without schedule() frame info, result given by
-        * thread_saved_pc() and get_wchan() are not reliable.
+        * thread_saved_pc() and __get_wchan() are not reliable.
         */
        if (schedule_mfi.pc_offset < 0)
                printk("Can't analyze schedule() prologue at %p\n", schedule);
 #endif
 
 /*
- * get_wchan - a maintenance nightmare^W^Wpain in the ass ...
+ * __get_wchan - a maintenance nightmare^W^Wpain in the ass ...
  */
-unsigned long get_wchan(struct task_struct *task)
+unsigned long __get_wchan(struct task_struct *task)
 {
        unsigned long pc = 0;
 #ifdef CONFIG_KALLSYMS
        unsigned long ra = 0;
 #endif
 
-       if (!task || task == current || task_is_running(task))
-               goto out;
        if (!task_stack_page(task))
                goto out;
 
 
 /* Prepare to copy thread state - unlazy all lazy status */
 #define prepare_to_copy(tsk)   do { } while (0)
 
-unsigned long get_wchan(struct task_struct *p);
+unsigned long __get_wchan(struct task_struct *p);
 
 #define cpu_relax()                    barrier()
 
 
 
 EXPORT_SYMBOL(dump_fpu);
 
-unsigned long get_wchan(struct task_struct *p)
+unsigned long __get_wchan(struct task_struct *p)
 {
        unsigned long fp, lr;
        unsigned long stack_start, stack_end;
        int count = 0;
 
-       if (!p || p == current || task_is_running(p))
-               return 0;
-
        if (IS_ENABLED(CONFIG_FRAME_POINTER)) {
                stack_start = (unsigned long)end_of_stack(p);
                stack_end = (unsigned long)task_stack_page(p) + THREAD_SIZE;
        }
        return 0;
 }
-
-EXPORT_SYMBOL(get_wchan);
 
 {
 }
 
-extern unsigned long get_wchan(struct task_struct *p);
+extern unsigned long __get_wchan(struct task_struct *p);
 
 #define task_pt_regs(p) \
        ((struct pt_regs *)(THREAD_SIZE + task_stack_page(p)) - 1)
 
        pr_emerg("\n\n");
 }
 
-unsigned long get_wchan(struct task_struct *p)
+unsigned long __get_wchan(struct task_struct *p)
 {
        unsigned long fp, pc;
        unsigned long stack_page;
        int count = 0;
 
-       if (!p || p == current || task_is_running(p))
-               return 0;
-
        stack_page = (unsigned long)p;
        fp = ((struct switch_stack *)p->thread.ksp)->fp;        /* ;dgt2 */
        do {
 
 
 void start_thread(struct pt_regs *regs, unsigned long nip, unsigned long sp);
 void release_thread(struct task_struct *);
-unsigned long get_wchan(struct task_struct *p);
+unsigned long __get_wchan(struct task_struct *p);
 
 #define cpu_relax()     barrier()
 
 
        dest[35] = 0;
 }
 
-unsigned long get_wchan(struct task_struct *p)
+unsigned long __get_wchan(struct task_struct *p)
 {
        /* TODO */
 
 
 /* Free all resources held by a thread. */
 extern void release_thread(struct task_struct *);
 
-extern unsigned long get_wchan(struct task_struct *p);
+extern unsigned long __get_wchan(struct task_struct *p);
 
 #define KSTK_EIP(tsk)  ((tsk)->thread.regs.iaoq[0])
 #define KSTK_ESP(tsk)  ((tsk)->thread.regs.gr[30])
 
 }
 
 unsigned long
-get_wchan(struct task_struct *p)
+__get_wchan(struct task_struct *p)
 {
        struct unwind_frame_info info;
        unsigned long ip;
        int count = 0;
 
-       if (!p || p == current || task_is_running(p))
-               return 0;
-
        /*
         * These bracket the sleeping functions..
         */
 
 
 #define task_pt_regs(tsk)      ((tsk)->thread.regs)
 
-unsigned long get_wchan(struct task_struct *p);
+unsigned long __get_wchan(struct task_struct *p);
 
 #define KSTK_EIP(tsk)  ((tsk)->thread.regs? (tsk)->thread.regs->nip: 0)
 #define KSTK_ESP(tsk)  ((tsk)->thread.regs? (tsk)->thread.regs->gpr[1]: 0)
 
 
 EXPORT_SYMBOL(validate_sp);
 
-static unsigned long __get_wchan(struct task_struct *p)
+static unsigned long ___get_wchan(struct task_struct *p)
 {
        unsigned long ip, sp;
        int count = 0;
 
-       if (!p || p == current || task_is_running(p))
-               return 0;
-
        sp = p->thread.ksp;
        if (!validate_sp(sp, p, STACK_FRAME_OVERHEAD))
                return 0;
        return 0;
 }
 
-unsigned long get_wchan(struct task_struct *p)
+unsigned long __get_wchan(struct task_struct *p)
 {
        unsigned long ret;
 
        if (!try_get_task_stack(p))
                return 0;
 
-       ret = __get_wchan(p);
+       ret = ___get_wchan(p);
 
        put_task_stack(p);
 
 
 {
 }
 
-extern unsigned long get_wchan(struct task_struct *p);
+extern unsigned long __get_wchan(struct task_struct *p);
 
 
 static inline void wait_for_interrupt(void)
 
        return true;
 }
 
-unsigned long get_wchan(struct task_struct *task)
+unsigned long __get_wchan(struct task_struct *task)
 {
        unsigned long pc = 0;
 
-       if (likely(task && task != current && !task_is_running(task))) {
-               if (!try_get_task_stack(task))
-                       return 0;
-               walk_stackframe(task, NULL, save_wchan, &pc);
-               put_task_stack(task);
-       }
+       if (!try_get_task_stack(task))
+               return 0;
+       walk_stackframe(task, NULL, save_wchan, &pc);
+       put_task_stack(task);
        return pc;
 }
 
 
 void guarded_storage_release(struct task_struct *tsk);
 void gs_load_bc_cb(struct pt_regs *regs);
 
-unsigned long get_wchan(struct task_struct *p);
+unsigned long __get_wchan(struct task_struct *p);
 #define task_pt_regs(tsk) ((struct pt_regs *) \
         (task_stack_page(tsk) + THREAD_SIZE) - 1)
 #define KSTK_EIP(tsk)  (task_pt_regs(tsk)->psw.addr)
 
        asm volatile("sfpc %0" : : "d" (0));
 }
 
-unsigned long get_wchan(struct task_struct *p)
+unsigned long __get_wchan(struct task_struct *p)
 {
        struct unwind_state state;
        unsigned long ip = 0;
 
-       if (!p || p == current || task_is_running(p) || !task_stack_page(p))
+       if (!task_stack_page(p))
                return 0;
 
        if (!try_get_task_stack(p))
 
 }
 #endif
 
-extern unsigned long get_wchan(struct task_struct *p);
+extern unsigned long __get_wchan(struct task_struct *p);
 
 #define KSTK_EIP(tsk)  (task_pt_regs(tsk)->pc)
 #define KSTK_ESP(tsk)  (task_pt_regs(tsk)->regs[15])
 
        return prev;
 }
 
-unsigned long get_wchan(struct task_struct *p)
+unsigned long __get_wchan(struct task_struct *p)
 {
        unsigned long pc;
 
-       if (!p || p == current || task_is_running(p))
-               return 0;
-
        /*
         * The same comment as on the Alpha applies here, too ...
         */
 
 /* Free all resources held by a thread. */
 #define release_thread(tsk)            do { } while(0)
 
-unsigned long get_wchan(struct task_struct *);
+unsigned long __get_wchan(struct task_struct *);
 
 #define task_pt_regs(tsk) ((tsk)->thread.kregs)
 #define KSTK_EIP(tsk)  ((tsk)->thread.kregs->pc)
 
 /* Free all resources held by a thread. */
 #define release_thread(tsk)            do { } while (0)
 
-unsigned long get_wchan(struct task_struct *task);
+unsigned long __get_wchan(struct task_struct *task);
 
 #define task_pt_regs(tsk) (task_thread_info(tsk)->kregs)
 #define KSTK_EIP(tsk)  (task_pt_regs(tsk)->tpc)
 
        return 0;
 }
 
-unsigned long get_wchan(struct task_struct *task)
+unsigned long __get_wchan(struct task_struct *task)
 {
        unsigned long pc, fp, bias = 0;
        unsigned long task_base = (unsigned long) task;
        struct reg_window32 *rw;
        int count = 0;
 
-       if (!task || task == current || task_is_running(task))
-               goto out;
-
        fp = task_thread_info(task)->ksp + bias;
        do {
                /* Bogus frame pointer? */
 
        return 0;
 }
 
-unsigned long get_wchan(struct task_struct *task)
+unsigned long __get_wchan(struct task_struct *task)
 {
        unsigned long pc, fp, bias = 0;
        struct thread_info *tp;
         unsigned long ret = 0;
        int count = 0; 
 
-       if (!task || task == current || task_is_running(task))
-               goto out;
-
        tp = task_thread_info(task);
        bias = STACK_BIAS;
        fp = task_thread_info(task)->ksp + bias;
 
 #define cache_line_size()      (boot_cpu_data.cache_alignment)
 
 #define KSTK_REG(tsk, reg) get_thread_reg(reg, &tsk->thread.switch_buf)
-extern unsigned long get_wchan(struct task_struct *p);
+extern unsigned long __get_wchan(struct task_struct *p);
 
 #endif
 
 }
 #endif
 
-unsigned long get_wchan(struct task_struct *p)
+unsigned long __get_wchan(struct task_struct *p)
 {
        unsigned long stack_page, sp, ip;
        bool seen_sched = 0;
 
-       if ((p == NULL) || (p == current) || task_is_running(p))
-               return 0;
-
        stack_page = (unsigned long) task_stack_page(p);
        /* Bail if the process has no kernel stack for some reason */
        if (stack_page == 0)
 
 /* Free all resources held by a thread. */
 extern void release_thread(struct task_struct *);
 
-unsigned long get_wchan(struct task_struct *p);
+unsigned long __get_wchan(struct task_struct *p);
 
 /*
  * Generic CPUID function
 
  * because the task might wake up and we might look at a stack
  * changing under us.
  */
-unsigned long get_wchan(struct task_struct *p)
+unsigned long __get_wchan(struct task_struct *p)
 {
        unsigned long entry = 0;
 
-       if (p == current || task_is_running(p))
-               return 0;
-
        stack_trace_save_tsk(p, &entry, 1, 0);
        return entry;
 }
 
 /* Free all resources held by a thread. */
 #define release_thread(thread) do { } while(0)
 
-extern unsigned long get_wchan(struct task_struct *p);
+extern unsigned long __get_wchan(struct task_struct *p);
 
 #define KSTK_EIP(tsk)          (task_pt_regs(tsk)->pc)
 #define KSTK_ESP(tsk)          (task_pt_regs(tsk)->areg[1])
 
  * These bracket the sleeping functions..
  */
 
-unsigned long get_wchan(struct task_struct *p)
+unsigned long __get_wchan(struct task_struct *p)
 {
        unsigned long sp, pc;
        unsigned long stack_page = (unsigned long) task_stack_page(p);
        int count = 0;
 
-       if (!p || p == current || task_is_running(p))
-               return 0;
-
        sp = p->thread.sp;
        pc = MAKE_PC_FROM_RA(p->thread.ra, p->thread.sp);
 
 
 #endif /* CONFIG_SMP */
 
 extern bool sched_task_on_rq(struct task_struct *p);
+extern unsigned long get_wchan(struct task_struct *p);
 
 /*
  * In order to reduce various lock holder preemption latencies provide an
 
        return task_on_rq_queued(p);
 }
 
+unsigned long get_wchan(struct task_struct *p)
+{
+       unsigned long ip = 0;
+       unsigned int state;
+
+       if (!p || p == current)
+               return 0;
+
+       /* Only get wchan if task is blocked and we can keep it that way. */
+       raw_spin_lock_irq(&p->pi_lock);
+       state = READ_ONCE(p->__state);
+       smp_rmb(); /* see try_to_wake_up() */
+       if (state != TASK_RUNNING && state != TASK_WAKING && !p->on_rq)
+               ip = __get_wchan(p);
+       raw_spin_unlock_irq(&p->pi_lock);
+
+       return ip;
+}
+
 static inline void enqueue_task(struct rq *rq, struct task_struct *p, int flags)
 {
        if (!(flags & ENQUEUE_NOCLOCK))