1 From 6f68de5f723e57e2709b468f55914fd0f963ce90 Mon Sep 17 00:00:00 2001
2 From: S.Çağlar Onur <caglar@cs.princeton.edu>
3 Date: Tue, 7 Dec 2010 11:09:43 -0500
4 Subject: [PATCH] linux-2.6-591-chopstix-intern.patch
6 block/blk-core.c: In function '__generic_make_request':
7 block/blk-core.c:1557: warning: assignment makes integer from pointer without a cast
8 fs/exec.c: In function 'open_exec':
9 fs/exec.c:698: warning: ISO C90 forbids mixed declarations and code
10 fs/bio.c: In function 'bio_endio':
11 fs/bio.c:1440: warning: assignment makes integer from pointer without a cast
12 mm/slab.c: In function '__cache_alloc':
13 mm/slab.c:3513: warning: assignment makes integer from pointer without a cast
14 mm/slab.c: In function '__cache_free':
15 mm/slab.c:3646: warning: assignment makes integer from pointer without a cast
19 arch/x86/kernel/asm-offsets_32.c | 25 +++++++++++
20 arch/x86/kernel/entry_32.S | 28 +++++++++++++
21 arch/x86/mm/fault.c | 10 +++++
22 block/blk-core.c | 29 +++++++++++++
23 drivers/oprofile/cpu_buffer.c | 30 ++++++++++++++
24 fs/bio.c | 31 ++++++++++++++
26 include/linux/arrays.h | 39 ++++++++++++++++++
27 include/linux/mutex.h | 2 +-
28 include/linux/sched.h | 5 ++
29 kernel/mutex.c | 55 +++++++++++++++++++++++++
30 kernel/sched.c | 82 +++++++++++++++++++++++++++++++++++++-
31 mm/memory.c | 29 +++++++++++++
32 mm/slab.c | 54 +++++++++++++++++++++++--
33 15 files changed, 429 insertions(+), 6 deletions(-)
34 create mode 100644 include/linux/arrays.h
36 diff --git a/arch/Kconfig b/arch/Kconfig
37 index b15fd1c..16a5734 100644
40 @@ -41,6 +41,14 @@ config OPROFILE_EVENT_MULTIPLEX
45 + bool "Chopstix (PlanetLab)"
46 + depends on MODULES && OPROFILE
48 + Chopstix allows you to monitor various events by summarizing them
49 + in lossy data structures and transferring these data structures
50 + into user space. If in doubt, say "N".
55 diff --git a/arch/x86/kernel/asm-offsets_32.c b/arch/x86/kernel/asm-offsets_32.c
56 index dfdbf64..29c79b8 100644
57 --- a/arch/x86/kernel/asm-offsets_32.c
58 +++ b/arch/x86/kernel/asm-offsets_32.c
60 #include <linux/signal.h>
61 #include <linux/personality.h>
62 #include <linux/suspend.h>
63 +#include <linux/arrays.h>
64 #include <linux/kbuild.h>
65 #include <asm/ucontext.h>
66 #include <asm/sigframe.h>
68 #include <linux/lguest.h>
69 #include "../../../drivers/lguest/lg.h"
71 +#ifdef CONFIG_CHOPSTIX
72 +#define STACKOFFSET(sym, str, mem) \
73 + DEFINE(sym, offsetof(struct str, mem)-sizeof(struct str));
77 + unsigned long dcookie;
79 + unsigned int number;
83 /* workaround for a warning with -Wmissing-prototypes */
86 @@ -51,6 +64,18 @@ void foo(void)
87 OFFSET(CPUINFO_x86_vendor_id, cpuinfo_x86, x86_vendor_id);
90 +#ifdef CONFIG_CHOPSTIX
91 + STACKOFFSET(TASK_thread, task_struct, thread);
92 + STACKOFFSET(THREAD_esp, thread_struct, sp);
93 + STACKOFFSET(EVENT_event_data, event, event_data);
94 + STACKOFFSET(EVENT_task, event, task);
95 + STACKOFFSET(EVENT_event_type, event, event_type);
96 + STACKOFFSET(SPEC_number, event_spec, number);
97 + DEFINE(EVENT_SIZE, sizeof(struct event));
98 + DEFINE(SPEC_SIZE, sizeof(struct event_spec));
99 + DEFINE(SPEC_EVENT_SIZE, sizeof(struct event_spec)+sizeof(struct event));
102 OFFSET(TI_task, thread_info, task);
103 OFFSET(TI_exec_domain, thread_info, exec_domain);
104 OFFSET(TI_flags, thread_info, flags);
105 diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S
106 index 21feb03..1109aac 100644
107 --- a/arch/x86/kernel/entry_32.S
108 +++ b/arch/x86/kernel/entry_32.S
109 @@ -526,6 +526,34 @@ ENTRY(system_call)
110 cmpl $(nr_syscalls), %eax
113 +#ifdef CONFIG_CHOPSTIX
114 + /* Move Chopstix syscall probe here */
115 + /* Save and clobber: eax, ecx, ebp */
120 + subl $SPEC_EVENT_SIZE, %esp
121 + movl rec_event, %ecx
124 + # struct event is first, just below %ebp
125 + movl %eax, (SPEC_number-EVENT_SIZE)(%ebp)
126 + leal -SPEC_EVENT_SIZE(%ebp), %eax
127 + movl %eax, EVENT_event_data(%ebp)
128 + movl $7, EVENT_event_type(%ebp)
129 + movl rec_event, %edx
131 + leal -EVENT_SIZE(%ebp), %eax
135 + addl $SPEC_EVENT_SIZE, %esp
141 call *sys_call_table(,%eax,4)
142 movl %eax,PT_EAX(%esp) # store the return value
144 diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
145 index a948561..76d32a6 100644
146 --- a/arch/x86/mm/fault.c
147 +++ b/arch/x86/mm/fault.c
148 @@ -62,6 +62,16 @@ static inline int notify_page_fault(struct pt_regs *regs)
152 +#ifdef CONFIG_CHOPSTIX
153 +extern void (*rec_event)(void *,unsigned int);
156 + unsigned long dcookie;
158 + unsigned char reason;
165 diff --git a/block/blk-core.c b/block/blk-core.c
166 index 5e1b914..2260822 100644
167 --- a/block/blk-core.c
168 +++ b/block/blk-core.c
170 #include <linux/writeback.h>
171 #include <linux/task_io_accounting_ops.h>
172 #include <linux/fault-inject.h>
173 +#include <linux/arrays.h>
175 #define CREATE_TRACE_POINTS
176 #include <trace/events/block.h>
180 +#ifdef CONFIG_CHOPSTIX
181 +extern void (*rec_event)(void *,unsigned int);
184 + unsigned long dcookie;
186 + unsigned char reason;
190 EXPORT_TRACEPOINT_SYMBOL_GPL(block_remap);
191 EXPORT_TRACEPOINT_SYMBOL_GPL(block_rq_remap);
192 EXPORT_TRACEPOINT_SYMBOL_GPL(block_bio_complete);
193 @@ -1535,6 +1546,24 @@ static inline void __generic_make_request(struct bio *bio)
195 trace_block_bio_queue(q, bio);
197 +#ifdef CONFIG_CHOPSTIX
199 + struct event event;
200 + struct event_spec espec;
203 + espec.reason = 0;/*request */
205 + eip = bio->bi_end_io;
206 + event.event_data=&espec;
208 + event.event_type=3;
209 + /* index in the event array currently set up */
210 + /* make sure the counters are loaded in the order we want them to show up*/
211 + (*rec_event)(&event, bio->bi_size);
215 ret = q->make_request_fn(q, bio);
218 diff --git a/drivers/oprofile/cpu_buffer.c b/drivers/oprofile/cpu_buffer.c
219 index de82183..1f1acf6 100644
220 --- a/drivers/oprofile/cpu_buffer.c
221 +++ b/drivers/oprofile/cpu_buffer.c
223 #include <linux/sched.h>
224 #include <linux/oprofile.h>
225 #include <linux/errno.h>
226 +#include <linux/arrays.h>
228 #include "event_buffer.h"
229 #include "cpu_buffer.h"
230 @@ -288,6 +289,17 @@ static inline void oprofile_end_trace(struct oprofile_cpu_buffer *cpu_buf)
231 cpu_buf->tracing = 0;
234 +#ifdef CONFIG_CHOPSTIX
238 + unsigned long dcookie;
242 +extern void (*rec_event)(void *,unsigned int);
246 __oprofile_add_ext_sample(unsigned long pc, struct pt_regs * const regs,
247 unsigned long event, int is_kernel)
248 @@ -322,7 +334,25 @@ void oprofile_add_sample(struct pt_regs * const regs, unsigned long event)
249 int is_kernel = !user_mode(regs);
250 unsigned long pc = profile_pc(regs);
252 +#ifdef CONFIG_CHOPSTIX
255 + struct event_spec espec;
256 + esig.task = current;
259 + esig.event_data = &espec;
260 + esig.event_type = event; /* index in the event array currently set up */
261 + /* make sure the counters are loaded in the order we want them to show up*/
262 + (*rec_event)(&esig, 1);
265 + __oprofile_add_ext_sample(pc, regs, event, is_kernel);
268 __oprofile_add_ext_sample(pc, regs, event, is_kernel);
274 diff --git a/fs/bio.c b/fs/bio.c
275 index e10d5b1..db37c70 100644
279 #include <linux/mempool.h>
280 #include <linux/workqueue.h>
281 #include <scsi/sg.h> /* for struct sg_iovec */
282 +#include <linux/arrays.h>
284 #include <trace/events/block.h>
286 @@ -48,6 +49,7 @@ struct biovec_slab bvec_slabs[BIOVEC_NR_POOLS] __read_mostly = {
292 * fs_bio_set is the bio_set containing bio and iovec memory pools used by
293 * IO code that does not need private memory pools.
294 @@ -1395,6 +1397,17 @@ void bio_check_pages_dirty(struct bio *bio)
298 +#ifdef CONFIG_CHOPSTIX
301 + unsigned long dcookie;
303 + unsigned char reason;
306 +extern void (*rec_event)(void *,unsigned int);
310 * bio_endio - end I/O on a bio
312 @@ -1416,6 +1429,24 @@ void bio_endio(struct bio *bio, int error)
313 else if (!test_bit(BIO_UPTODATE, &bio->bi_flags))
316 +#ifdef CONFIG_CHOPSTIX
318 + struct event event;
319 + struct event_spec espec;
322 + espec.reason = 1;/*response */
324 + eip = bio->bi_end_io;
325 + event.event_data=&espec;
327 + event.event_type=3;
328 + /* index in the event array currently set up */
329 + /* make sure the counters are loaded in the order we want them to show up*/
330 + (*rec_event)(&event, bio->bi_size);
335 bio->bi_end_io(bio, error);
337 diff --git a/fs/exec.c b/fs/exec.c
338 index f42d519..5ac9745 100644
342 #include <linux/fdtable.h>
343 #include <linux/mm.h>
344 #include <linux/stat.h>
345 +#include <linux/dcookies.h>
346 #include <linux/fcntl.h>
347 #include <linux/smp_lock.h>
348 #include <linux/swap.h>
349 @@ -693,6 +694,13 @@ struct file *open_exec(const char *name)
353 +#ifdef CONFIG_CHOPSTIX
354 + unsigned long cookie;
355 + extern void (*rec_event)(void *, unsigned int);
356 + if (rec_event && !(file->f_path.dentry->d_flags & DCACHE_COOKIE))
357 + get_dcookie(&file->f_path, &cookie);
363 diff --git a/include/linux/arrays.h b/include/linux/arrays.h
365 index 0000000..7641a3c
367 +++ b/include/linux/arrays.h
369 +#ifndef __ARRAYS_H__
370 +#define __ARRAYS_H__
371 +#include <linux/list.h>
373 +#define SAMPLING_METHOD_DEFAULT 0
374 +#define SAMPLING_METHOD_LOG 1
376 +#define DEFAULT_ARRAY_SIZE 2048
378 +/* Every probe has an array handler */
380 +/* XXX - Optimize this structure */
382 +extern void (*rec_event)(void *,unsigned int);
383 +struct array_handler {
384 + struct list_head link;
385 + unsigned int (*hash_func)(void *);
386 + unsigned int (*sampling_func)(void *,int,void *);
387 + unsigned short size;
388 + unsigned int threshold;
389 + unsigned char **expcount;
390 + unsigned int sampling_method;
391 + unsigned int **arrays;
392 + unsigned int arraysize;
393 + unsigned int num_samples[2];
394 + void **epoch_samples; /* size-sized lists of samples */
395 + unsigned int (*serialize)(void *, void *);
396 + unsigned char code[5];
397 + unsigned int last_threshold;
401 + struct list_head link;
403 + unsigned int count;
404 + unsigned int event_type;
405 + struct task_struct *task;
408 diff --git a/include/linux/mutex.h b/include/linux/mutex.h
409 index 878cab4..6c21914 100644
410 --- a/include/linux/mutex.h
411 +++ b/include/linux/mutex.h
412 @@ -50,7 +50,7 @@ struct mutex {
414 spinlock_t wait_lock;
415 struct list_head wait_list;
416 -#if defined(CONFIG_DEBUG_MUTEXES) || defined(CONFIG_SMP)
417 +#if defined(CONFIG_DEBUG_MUTEXES) || defined(CONFIG_SMP) || defined(CONFIG_CHOPSTIX)
418 struct thread_info *owner;
420 #ifdef CONFIG_DEBUG_MUTEXES
421 diff --git a/include/linux/sched.h b/include/linux/sched.h
422 index caf30e1..6d60b0f 100644
423 --- a/include/linux/sched.h
424 +++ b/include/linux/sched.h
425 @@ -1351,6 +1351,11 @@ struct task_struct {
426 cputime_t utime, stime, utimescaled, stimescaled;
428 cputime_t prev_utime, prev_stime;
430 + #ifdef CONFIG_CHOPSTIX
431 + unsigned long last_interrupted, last_ran_j;
434 unsigned long nvcsw, nivcsw; /* context switch counts */
435 struct timespec start_time; /* monotonic time */
436 struct timespec real_start_time; /* boot based time */
437 diff --git a/kernel/mutex.c b/kernel/mutex.c
438 index e04aa45..196ac04 100644
442 #include <linux/spinlock.h>
443 #include <linux/interrupt.h>
444 #include <linux/debug_locks.h>
445 +#include <linux/arrays.h>
447 +#ifdef CONFIG_CHOPSTIX
450 + unsigned long dcookie;
452 + unsigned char reason;
457 * In the DEBUG case we are using the "NULL fastpath" for mutexes,
458 @@ -49,6 +59,9 @@ void
459 __mutex_init(struct mutex *lock, const char *name, struct lock_class_key *key)
461 atomic_set(&lock->count, 1);
462 +#ifdef CONFIG_CHOPSTIX
463 + lock->owner = NULL;
465 spin_lock_init(&lock->wait_lock);
466 INIT_LIST_HEAD(&lock->wait_list);
467 mutex_clear_owner(lock);
468 @@ -254,6 +267,25 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass,
470 __set_task_state(task, state);
472 +#if 0 && CONFIG_CHOPSTIX
475 + struct event event;
476 + struct event_spec espec;
477 + struct task_struct *p = lock->owner->task;
479 + espec.reason = 0; /* lock */
480 + event.event_data = &espec;
483 + event.event_type = 5;
484 + (*rec_event)(&event, 1);
491 /* didnt get the lock, go to sleep: */
492 spin_unlock_mutex(&lock->wait_lock, flags);
493 preempt_enable_no_resched();
494 @@ -268,6 +300,10 @@ done:
495 mutex_remove_waiter(lock, &waiter, current_thread_info());
496 mutex_set_owner(lock);
498 +#ifdef CONFIG_CHOPSTIX
499 + lock->owner = task_thread_info(task);
502 /* set it to 0 if there are no waiters left: */
503 if (likely(list_empty(&lock->wait_list)))
504 atomic_set(&lock->count, 0);
505 @@ -338,6 +374,25 @@ __mutex_unlock_common_slowpath(atomic_t *lock_count, int nested)
507 debug_mutex_wake_waiter(lock, waiter);
509 +#if 0 && CONFIG_CHOPSTIX
512 + struct event event;
513 + struct event_spec espec;
514 + struct task_struct *p = lock->owner->task;
516 + espec.reason = 1; /* unlock */
517 + event.event_data = &espec;
520 + event.event_type = 5;
521 + (*rec_event)(&event, 1);
528 wake_up_process(waiter->task);
531 diff --git a/kernel/sched.c b/kernel/sched.c
532 index dd8a4df..345645b 100644
536 * 1998-11-19 Implemented schedule_timeout() and related stuff
537 * by Andrea Arcangeli
538 * 2002-01-04 New ultra-scalable O(1) scheduler by Ingo Molnar:
539 - * hybrid priority-list and round-robin design with
540 + * hybrid priority-list and round-robin deventn with
541 * an array-switch method of distributing timeslices
542 * and per-CPU runqueues. Cleanups and useful suggestions
543 * by Davide Libenzi, preemptible kernel bits by Robert Love.
545 #include <linux/ftrace.h>
546 #include <linux/vs_sched.h>
547 #include <linux/vs_cvirt.h>
548 +#include <linux/arrays.h>
551 #include <asm/irq_regs.h>
553 #include "sched_cpupri.h"
555 +#define INTERRUPTIBLE -1
558 #define CREATE_TRACE_POINTS
559 #include <trace/events/sched.h>
561 @@ -2719,6 +2723,10 @@ static void __sched_fork(struct task_struct *p)
562 INIT_HLIST_HEAD(&p->preempt_notifiers);
565 +#ifdef CONFIG_CHOPSTIX
566 + p->last_ran_j = jiffies;
567 + p->last_interrupted = INTERRUPTIBLE;
570 * We mark the process as running here, but have not actually
571 * inserted it onto the runqueue yet. This guarantees that
572 @@ -5764,6 +5772,30 @@ pick_next_task(struct rq *rq)
576 +#ifdef CONFIG_CHOPSTIX
577 +void (*rec_event)(void *,unsigned int) = NULL;
578 +EXPORT_SYMBOL(rec_event);
579 +EXPORT_SYMBOL(in_sched_functions);
583 + unsigned long dcookie;
584 + unsigned int count;
585 + unsigned int reason;
588 +/* To support safe calling from asm */
589 +asmlinkage void rec_event_asm (struct event *event_signature_in, unsigned int count) {
590 + struct pt_regs *regs;
591 + struct event_spec *es = event_signature_in->event_data;
592 + regs = task_pt_regs(current);
593 + event_signature_in->task=current;
595 + event_signature_in->count=1;
596 + (*rec_event)(event_signature_in, count);
601 * schedule() is the main scheduler function.
603 @@ -5811,6 +5843,54 @@ need_resched_nonpreemptible:
604 next = pick_next_task(rq);
606 if (likely(prev != next)) {
608 +#ifdef CONFIG_CHOPSTIX
609 + /* Run only if the Chopstix module so decrees it */
611 + unsigned long diff;
612 + int sampling_reason;
613 + prev->last_ran_j = jiffies;
614 + if (next->last_interrupted!=INTERRUPTIBLE) {
615 + if (next->last_interrupted!=RUNNING) {
616 + diff = (jiffies-next->last_interrupted);
617 + sampling_reason = 0;/* BLOCKING */
620 + diff = jiffies-next->last_ran_j;
621 + sampling_reason = 1;/* PREEMPTION */
624 + if (diff >= HZ/10) {
625 + struct event event;
626 + struct event_spec espec;
627 + struct pt_regs *regs;
628 + regs = task_pt_regs(current);
630 + espec.reason = sampling_reason;
631 + event.event_data=&espec;
634 + event.event_type=2;
635 + /* index in the event array currently set up */
636 + /* make sure the counters are loaded in the order we want them to show up*/
637 + (*rec_event)(&event, diff);
640 + /* next has been elected to run */
641 + next->last_interrupted=0;
643 + /* An uninterruptible process just yielded. Record the current jiffy */
644 + if (prev->state & TASK_UNINTERRUPTIBLE) {
645 + prev->last_interrupted=jiffies;
647 + /* An interruptible process just yielded, or it got preempted.
648 + * Mark it as interruptible */
649 + else if (prev->state & TASK_INTERRUPTIBLE) {
650 + prev->last_interrupted=INTERRUPTIBLE;
655 sched_info_switch(prev, next);
656 perf_event_task_sched_out(prev, next);
658 diff --git a/mm/memory.c b/mm/memory.c
659 index 30858a5..b9a9d9f 100644
663 #include <linux/swapops.h>
664 #include <linux/elf.h>
665 // #include <linux/vs_memory.h>
666 +#include <linux/arrays.h>
669 #include <asm/pgalloc.h>
670 @@ -3152,6 +3153,16 @@ out:
674 +#ifdef CONFIG_CHOPSTIX
675 +extern void (*rec_event)(void *,unsigned int);
678 + unsigned long dcookie;
680 + unsigned char reason;
685 * By the time we get here, we already hold the mm semaphore
687 @@ -3197,6 +3208,24 @@ int handle_mm_fault(struct mm_struct *mm, struct vm_area_struct *vma,
691 +#ifdef CONFIG_CHOPSTIX
693 + struct event event;
694 + struct event_spec espec;
695 + struct pt_regs *regs;
697 + regs = task_pt_regs(current);
698 + pc = regs->ip & (unsigned int) ~4095;
700 + espec.reason = 0; /* alloc */
701 + event.event_data=&espec;
702 + event.task = current;
704 + event.event_type = 6;
705 + (*rec_event)(&event, 1);
709 return handle_pte_fault(mm, vma, address, pte, pmd, flags);
712 diff --git a/mm/slab.c b/mm/slab.c
713 index f644e70..6a5489c 100644
717 #include <linux/fault-inject.h>
718 #include <linux/rtmutex.h>
719 #include <linux/reciprocal_div.h>
720 +#include <linux/arrays.h>
721 #include <linux/debugobjects.h>
722 #include <linux/kmemcheck.h>
723 #include <linux/memory.h>
724 @@ -253,6 +254,16 @@ struct slab_rcu {
728 +#ifdef CONFIG_CHOPSTIX
729 +extern void (*rec_event)(void *,unsigned int);
732 + unsigned long dcookie;
734 + unsigned char reason;
741 @@ -3491,6 +3502,19 @@ __cache_alloc(struct kmem_cache *cachep, gfp_t flags, void *caller)
742 kmemleak_alloc_recursive(objp, obj_size(cachep), 1, cachep->flags,
745 +#ifdef CONFIG_CHOPSTIX
746 + if (rec_event && objp) {
747 + struct event event;
748 + struct event_spec espec;
750 + espec.reason = 0; /* alloc */
751 + event.event_data=&espec;
752 + event.task = current;
754 + event.event_type=4;
755 + (*rec_event)(&event, cachep->buffer_size);
760 kmemcheck_slab_alloc(cachep, flags, objp, obj_size(cachep));
761 @@ -3603,13 +3627,28 @@ free_done:
762 * Release an obj back to its cache. If the obj has a constructed state, it must
763 * be in this state _before_ it is released. Called with disabled ints.
765 -static inline void __cache_free(struct kmem_cache *cachep, void *objp)
766 +static inline void __cache_free(struct kmem_cache *cachep, void *objp, void *caller)
768 struct array_cache *ac = cpu_cache_get(cachep);
771 kmemleak_free_recursive(objp, cachep->flags);
772 - objp = cache_free_debugcheck(cachep, objp, __builtin_return_address(0));
773 + objp = cache_free_debugcheck(cachep, objp, caller);
775 +#ifdef CONFIG_CHOPSTIX
776 + if (rec_event && objp) {
777 + struct event event;
778 + struct event_spec espec;
780 + espec.reason = 1; /* free */
781 + event.event_data = &espec;
782 + event.task = current;
784 + event.event_type = 4;
785 + (*rec_event)(&event, cachep->buffer_size);
789 vx_slab_free(cachep);
791 kmemcheck_slab_free(cachep, objp, obj_size(cachep));
792 @@ -3811,10 +3850,17 @@ void *__kmalloc_track_caller(size_t size, gfp_t flags, unsigned long caller)
793 EXPORT_SYMBOL(__kmalloc_track_caller);
796 +#ifdef CONFIG_CHOPSTIX
797 +void *__kmalloc(size_t size, gfp_t flags)
799 + return __do_kmalloc(size, flags, __builtin_return_address(0));
802 void *__kmalloc(size_t size, gfp_t flags)
804 return __do_kmalloc(size, flags, NULL);
807 EXPORT_SYMBOL(__kmalloc);
810 @@ -3834,7 +3880,7 @@ void kmem_cache_free(struct kmem_cache *cachep, void *objp)
811 debug_check_no_locks_freed(objp, obj_size(cachep));
812 if (!(cachep->flags & SLAB_DEBUG_OBJECTS))
813 debug_check_no_obj_freed(objp, obj_size(cachep));
814 - __cache_free(cachep, objp);
815 + __cache_free(cachep, objp,__builtin_return_address(0));
816 local_irq_restore(flags);
818 trace_kmem_cache_free(_RET_IP_, objp);
819 @@ -3864,7 +3910,7 @@ void kfree(const void *objp)
820 c = virt_to_cache(objp);
821 debug_check_no_locks_freed(objp, obj_size(c));
822 debug_check_no_obj_freed(objp, obj_size(c));
823 - __cache_free(c, (void *)objp);
824 + __cache_free(c, (void *)objp,__builtin_return_address(0));
825 local_irq_restore(flags);
827 EXPORT_SYMBOL(kfree);