From c5b5a5993234d4db2079e57e456bda5278ef59cf Mon Sep 17 00:00:00 2001 From: Hidetoshi Seto Date: Wed, 30 Apr 2008 16:51:06 +0900 Subject: [IA64] fix section mismatch in arch/ia64/kernel/acpi.c This patch kills: WARNING: vmlinux.o(.text+0x1702): Section mismatch in reference from the function acpi_register_ioapic() to the function .devinit.text:iosapic_init() Signed-off-by: Hidetoshi Seto Signed-off-by: Tony Luck --- arch/ia64/kernel/acpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c index c7467f863c7..19709a07963 100644 --- a/arch/ia64/kernel/acpi.c +++ b/arch/ia64/kernel/acpi.c @@ -966,7 +966,7 @@ acpi_map_iosapics (void) fs_initcall(acpi_map_iosapics); #endif /* CONFIG_ACPI_NUMA */ -int acpi_register_ioapic(acpi_handle handle, u64 phys_addr, u32 gsi_base) +int __ref acpi_register_ioapic(acpi_handle handle, u64 phys_addr, u32 gsi_base) { int err; -- cgit v1.2.3-70-g09d2 From 751fc7849d623bcd5e77fd494b01662599a8dccf Mon Sep 17 00:00:00 2001 From: Hidetoshi Seto Date: Wed, 30 Apr 2008 16:50:43 +0900 Subject: [IA64] fix section mismatch in arch/ia64/kernel/irq.c This patch shuts up the following: WARNING: vmlinux.o(.text+0x7102): Section mismatch in reference from the function fixup_irqs() to the function .devinit.text:ia64_disable_timer() Removing ia64_disable_timer() is safe because there are no functions calling it other than the fixup_irqs(), Signed-off-by: Hidetoshi Seto Signed-off-by: Tony Luck --- arch/ia64/kernel/irq.c | 4 ++-- arch/ia64/kernel/time.c | 5 ----- 2 files changed, 2 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/ia64/kernel/irq.c b/arch/ia64/kernel/irq.c index 6dee579f205..7fd18f54c05 100644 --- a/arch/ia64/kernel/irq.c +++ b/arch/ia64/kernel/irq.c @@ -183,10 +183,10 @@ void fixup_irqs(void) { unsigned int irq; extern void ia64_process_pending_intr(void); - extern void ia64_disable_timer(void); extern volatile int time_keeper_id; - ia64_disable_timer(); + /* Mask ITV to disable timer */ + ia64_set_itv(1 << 16); /* * Find a new timesync master diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c index 48e15a51782..8c73643f2d6 100644 --- a/arch/ia64/kernel/time.c +++ b/arch/ia64/kernel/time.c @@ -379,11 +379,6 @@ static struct irqaction timer_irqaction = { .name = "timer" }; -void __devinit ia64_disable_timer(void) -{ - ia64_set_itv(1 << 16); -} - void __init time_init (void) { -- cgit v1.2.3-70-g09d2 From 9d4efae68714e24d40b628461bc4182e330969b1 Mon Sep 17 00:00:00 2001 From: Hidetoshi Seto Date: Wed, 30 Apr 2008 16:50:22 +0900 Subject: [IA64] fix section mismatch in arch/ia64/kernel/palinfo.c This patch removes following warning: WARNING: vmlinux.o(.exit.text+0xb1): Section mismatch in reference from the function palinfo_exit() to the variable .cpuinit.data:palinfo_cpu_notifier Signed-off-by: Hidetoshi Seto Signed-off-by: Tony Luck --- arch/ia64/kernel/palinfo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/ia64/kernel/palinfo.c b/arch/ia64/kernel/palinfo.c index 396004e8cd1..4547a2092af 100644 --- a/arch/ia64/kernel/palinfo.c +++ b/arch/ia64/kernel/palinfo.c @@ -1053,7 +1053,7 @@ static int __cpuinit palinfo_cpu_callback(struct notifier_block *nfb, return NOTIFY_OK; } -static struct notifier_block palinfo_cpu_notifier __cpuinitdata = +static struct notifier_block __refdata palinfo_cpu_notifier = { .notifier_call = palinfo_cpu_callback, .priority = 0, -- cgit v1.2.3-70-g09d2 From 6d3c51110819918617d9e2d1da7ff53f4b2c1187 Mon Sep 17 00:00:00 2001 From: Hidetoshi Seto Date: Wed, 30 Apr 2008 16:50:55 +0900 Subject: [IA64] fix section mismatch in arch/ia64/kernel/topology.c This patch silences: WARNING: vmlinux.o(.text+0x44672): Section mismatch in reference from the function arch_register_cpu() to the function .cpuinit.text:register_cpu() Changes are based on codes in arch/x86/kernel/topology.c Signed-off-by: Hidetoshi Seto Signed-off-by: Tony Luck --- arch/ia64/kernel/topology.c | 16 ++++++++++------ include/asm-ia64/cpu.h | 2 +- 2 files changed, 11 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/ia64/kernel/topology.c b/arch/ia64/kernel/topology.c index abb17a613b1..26228e2d01a 100644 --- a/arch/ia64/kernel/topology.c +++ b/arch/ia64/kernel/topology.c @@ -36,9 +36,11 @@ void arch_fix_phys_package_id(int num, u32 slot) } EXPORT_SYMBOL_GPL(arch_fix_phys_package_id); -int arch_register_cpu(int num) + +#ifdef CONFIG_HOTPLUG_CPU +int __ref arch_register_cpu(int num) { -#if defined (CONFIG_ACPI) && defined (CONFIG_HOTPLUG_CPU) +#ifdef CONFIG_ACPI /* * If CPEI can be re-targetted or if this is not * CPEI target, then it is hotpluggable @@ -47,19 +49,21 @@ int arch_register_cpu(int num) sysfs_cpus[num].cpu.hotpluggable = 1; map_cpu_to_node(num, node_cpuid[num].nid); #endif - return register_cpu(&sysfs_cpus[num].cpu, num); } - -#ifdef CONFIG_HOTPLUG_CPU +EXPORT_SYMBOL(arch_register_cpu); void arch_unregister_cpu(int num) { unregister_cpu(&sysfs_cpus[num].cpu); unmap_cpu_from_node(num, cpu_to_node(num)); } -EXPORT_SYMBOL(arch_register_cpu); EXPORT_SYMBOL(arch_unregister_cpu); +#else +static int __init arch_register_cpu(int num) +{ + return register_cpu(&sysfs_cpus[num].cpu, num); +} #endif /*CONFIG_HOTPLUG_CPU*/ diff --git a/include/asm-ia64/cpu.h b/include/asm-ia64/cpu.h index e87fa3210a2..fcca30b9f11 100644 --- a/include/asm-ia64/cpu.h +++ b/include/asm-ia64/cpu.h @@ -14,8 +14,8 @@ DECLARE_PER_CPU(struct ia64_cpu, cpu_devices); DECLARE_PER_CPU(int, cpu_state); -extern int arch_register_cpu(int num); #ifdef CONFIG_HOTPLUG_CPU +extern int arch_register_cpu(int num); extern void arch_unregister_cpu(int); #endif -- cgit v1.2.3-70-g09d2 From c0cd661b1b0ad83dac54420169ec9ca14df409e9 Mon Sep 17 00:00:00 2001 From: Hidetoshi Seto Date: Wed, 30 Apr 2008 18:55:48 +0900 Subject: [IA64] smp.c coding style fix Fix indenting of switch statement to follow CodingStyle, and pull out handling of call_data into an inlined function. I confirmed that applying this fix doesn't affect assembled code. Signed-off-by: Hidetoshi Seto Signed-off-by: Tony Luck --- arch/ia64/kernel/smp.c | 68 ++++++++++++++++++++++++++------------------------ 1 file changed, 35 insertions(+), 33 deletions(-) (limited to 'arch') diff --git a/arch/ia64/kernel/smp.c b/arch/ia64/kernel/smp.c index 9a9d4c48933..983296f1c81 100644 --- a/arch/ia64/kernel/smp.c +++ b/arch/ia64/kernel/smp.c @@ -98,8 +98,33 @@ unlock_ipi_calllock(void) spin_unlock_irq(&call_lock); } +static inline void +handle_call_data(void) +{ + struct call_data_struct *data; + void (*func)(void *info); + void *info; + int wait; + + /* release the 'pointer lock' */ + data = (struct call_data_struct *)call_data; + func = data->func; + info = data->info; + wait = data->wait; + + mb(); + atomic_inc(&data->started); + /* At this point the structure may be gone unless wait is true. */ + (*func)(info); + + /* Notify the sending CPU that the task is done. */ + mb(); + if (wait) + atomic_inc(&data->finished); +} + static void -stop_this_cpu (void) +stop_this_cpu(void) { /* * Remove this CPU: @@ -138,44 +163,21 @@ handle_IPI (int irq, void *dev_id) ops &= ~(1 << which); switch (which) { - case IPI_CALL_FUNC: - { - struct call_data_struct *data; - void (*func)(void *info); - void *info; - int wait; - - /* release the 'pointer lock' */ - data = (struct call_data_struct *) call_data; - func = data->func; - info = data->info; - wait = data->wait; - - mb(); - atomic_inc(&data->started); - /* - * At this point the structure may be gone unless - * wait is true. - */ - (*func)(info); - - /* Notify the sending CPU that the task is done. */ - mb(); - if (wait) - atomic_inc(&data->finished); - } - break; - - case IPI_CPU_STOP: + case IPI_CALL_FUNC: + handle_call_data(); + break; + + case IPI_CPU_STOP: stop_this_cpu(); break; #ifdef CONFIG_KEXEC - case IPI_KDUMP_CPU_STOP: + case IPI_KDUMP_CPU_STOP: unw_init_running(kdump_cpu_freeze, NULL); break; #endif - default: - printk(KERN_CRIT "Unknown IPI on CPU %d: %lu\n", this_cpu, which); + default: + printk(KERN_CRIT "Unknown IPI on CPU %d: %lu\n", + this_cpu, which); break; } } while (ops); -- cgit v1.2.3-70-g09d2 From 848376c774a941c29e4fa083d96d84a5f2190857 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Wed, 30 Apr 2008 14:40:14 -0700 Subject: [IA64] TS_RESTORE_SIGMASK Replace TIF_RESTORE_SIGMASK with TS_RESTORE_SIGMASK and define our own set_restore_sigmask() function. This saves the costly SMP-safe set_bit operation, which we do not need for the sigmask flag since TIF_SIGPENDING always has to be set too. Signed-off-by: Roland McGrath Signed-off-by: Tony Luck --- arch/ia64/ia32/ia32_signal.c | 2 +- arch/ia64/kernel/signal.c | 15 ++++++++------- include/asm-ia64/thread_info.h | 13 +++++++++++-- 3 files changed, 20 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/ia64/ia32/ia32_signal.c b/arch/ia64/ia32/ia32_signal.c index 256a7faeda0..b763ca19ef1 100644 --- a/arch/ia64/ia32/ia32_signal.c +++ b/arch/ia64/ia32/ia32_signal.c @@ -463,7 +463,7 @@ sys32_sigsuspend (int history0, int history1, old_sigset_t mask) current->state = TASK_INTERRUPTIBLE; schedule(); - set_thread_flag(TIF_RESTORE_SIGMASK); + set_restore_sigmask(); return -ERESTARTNOHAND; } diff --git a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c index 5740296c35a..19c5a78636f 100644 --- a/arch/ia64/kernel/signal.c +++ b/arch/ia64/kernel/signal.c @@ -464,7 +464,7 @@ ia64_do_signal (struct sigscratch *scr, long in_syscall) if (!user_mode(&scr->pt)) return; - if (test_thread_flag(TIF_RESTORE_SIGMASK)) + if (current_thread_info()->status & TS_RESTORE_SIGMASK) oldset = ¤t->saved_sigmask; else oldset = ¤t->blocked; @@ -530,12 +530,13 @@ ia64_do_signal (struct sigscratch *scr, long in_syscall) * continue to iterate in this loop so we can deliver the SIGSEGV... */ if (handle_signal(signr, &ka, &info, oldset, scr)) { - /* a signal was successfully delivered; the saved + /* + * A signal was successfully delivered; the saved * sigmask will have been stored in the signal frame, * and will be restored by sigreturn, so we can simply - * clear the TIF_RESTORE_SIGMASK flag */ - if (test_thread_flag(TIF_RESTORE_SIGMASK)) - clear_thread_flag(TIF_RESTORE_SIGMASK); + * clear the TS_RESTORE_SIGMASK flag. + */ + current_thread_info()->status &= ~TS_RESTORE_SIGMASK; return; } } @@ -566,8 +567,8 @@ ia64_do_signal (struct sigscratch *scr, long in_syscall) /* if there's no signal to deliver, we just put the saved sigmask * back */ - if (test_thread_flag(TIF_RESTORE_SIGMASK)) { - clear_thread_flag(TIF_RESTORE_SIGMASK); + if (current_thread_info()->status & TS_RESTORE_SIGMASK) { + current_thread_info()->status &= ~TS_RESTORE_SIGMASK; sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); } } diff --git a/include/asm-ia64/thread_info.h b/include/asm-ia64/thread_info.h index f30e0558386..2422ac61658 100644 --- a/include/asm-ia64/thread_info.h +++ b/include/asm-ia64/thread_info.h @@ -108,13 +108,11 @@ extern void tsk_clear_notify_resume(struct task_struct *tsk); #define TIF_DB_DISABLED 19 /* debug trap disabled for fsyscall */ #define TIF_FREEZE 20 /* is freezing for suspend */ #define TIF_RESTORE_RSE 21 /* user RBS is newer than kernel RBS */ -#define TIF_RESTORE_SIGMASK 22 /* restore signal mask in do_signal() */ #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) #define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP) #define _TIF_SYSCALL_TRACEAUDIT (_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP) -#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK) #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) #define _TIF_SIGPENDING (1 << TIF_SIGPENDING) #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) @@ -131,7 +129,18 @@ extern void tsk_clear_notify_resume(struct task_struct *tsk); #define TIF_WORK_MASK (TIF_ALLWORK_MASK&~(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT)) #define TS_POLLING 1 /* true if in idle loop and not sleeping */ +#define TS_RESTORE_SIGMASK 2 /* restore signal mask in do_signal() */ #define tsk_is_polling(t) (task_thread_info(t)->status & TS_POLLING) +#ifndef __ASSEMBLY__ +#define HAVE_SET_RESTORE_SIGMASK 1 +static inline void set_restore_sigmask(void) +{ + struct thread_info *ti = current_thread_info(); + ti->status |= TS_RESTORE_SIGMASK; + set_bit(TIF_SIGPENDING, &ti->flags); +} +#endif /* !__ASSEMBLY__ */ + #endif /* _ASM_IA64_THREAD_INFO_H */ -- cgit v1.2.3-70-g09d2 From f8e811b98935f702b48abc92563462a15c226eb8 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 1 May 2008 14:36:36 -0700 Subject: [IA64] fix file and descriptor handling in perfmon Races galore... General rule: as soon as it's in descriptor table, it's over; another thread might have started IO on it/dup2() it elsewhere/dup2() something *over* it/etc. fd_install() is the very last step one should take - it's a point of no return. Besides, the damn thing leaked on failure exits... Signed-off-by: Al Viro Signed-off-by: Tony Luck --- arch/ia64/kernel/perfmon.c | 199 ++++++++++++++++++++------------------------- 1 file changed, 87 insertions(+), 112 deletions(-) (limited to 'arch') diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c index 7fbb51e10bb..c1ad27de2dd 100644 --- a/arch/ia64/kernel/perfmon.c +++ b/arch/ia64/kernel/perfmon.c @@ -867,7 +867,7 @@ pfm_rvfree(void *mem, unsigned long size) } static pfm_context_t * -pfm_context_alloc(void) +pfm_context_alloc(int ctx_flags) { pfm_context_t *ctx; @@ -878,6 +878,46 @@ pfm_context_alloc(void) ctx = kzalloc(sizeof(pfm_context_t), GFP_KERNEL); if (ctx) { DPRINT(("alloc ctx @%p\n", ctx)); + + /* + * init context protection lock + */ + spin_lock_init(&ctx->ctx_lock); + + /* + * context is unloaded + */ + ctx->ctx_state = PFM_CTX_UNLOADED; + + /* + * initialization of context's flags + */ + ctx->ctx_fl_block = (ctx_flags & PFM_FL_NOTIFY_BLOCK) ? 1 : 0; + ctx->ctx_fl_system = (ctx_flags & PFM_FL_SYSTEM_WIDE) ? 1: 0; + ctx->ctx_fl_no_msg = (ctx_flags & PFM_FL_OVFL_NO_MSG) ? 1: 0; + /* + * will move to set properties + * ctx->ctx_fl_excl_idle = (ctx_flags & PFM_FL_EXCL_IDLE) ? 1: 0; + */ + + /* + * init restart semaphore to locked + */ + init_completion(&ctx->ctx_restart_done); + + /* + * activation is used in SMP only + */ + ctx->ctx_last_activation = PFM_INVALID_ACTIVATION; + SET_LAST_CPU(ctx, -1); + + /* + * initialize notification message queue + */ + ctx->ctx_msgq_head = ctx->ctx_msgq_tail = 0; + init_waitqueue_head(&ctx->ctx_msgq_wait); + init_waitqueue_head(&ctx->ctx_zombieq); + } return ctx; } @@ -2165,28 +2205,21 @@ static struct dentry_operations pfmfs_dentry_operations = { }; -static int -pfm_alloc_fd(struct file **cfile) +static struct file * +pfm_alloc_file(pfm_context_t *ctx) { - int fd, ret = 0; - struct file *file = NULL; - struct inode * inode; + struct file *file; + struct inode *inode; + struct dentry *dentry; char name[32]; struct qstr this; - fd = get_unused_fd(); - if (fd < 0) return -ENFILE; - - ret = -ENFILE; - - file = get_empty_filp(); - if (!file) goto out; - /* * allocate a new inode */ inode = new_inode(pfmfs_mnt->mnt_sb); - if (!inode) goto out; + if (!inode) + return ERR_PTR(-ENOMEM); DPRINT(("new inode ino=%ld @%p\n", inode->i_ino, inode)); @@ -2199,59 +2232,28 @@ pfm_alloc_fd(struct file **cfile) this.len = strlen(name); this.hash = inode->i_ino; - ret = -ENOMEM; - /* * allocate a new dcache entry */ - file->f_path.dentry = d_alloc(pfmfs_mnt->mnt_sb->s_root, &this); - if (!file->f_path.dentry) goto out; + dentry = d_alloc(pfmfs_mnt->mnt_sb->s_root, &this); + if (!dentry) { + iput(inode); + return ERR_PTR(-ENOMEM); + } - file->f_path.dentry->d_op = &pfmfs_dentry_operations; + dentry->d_op = &pfmfs_dentry_operations; + d_add(dentry, inode); - d_add(file->f_path.dentry, inode); - file->f_path.mnt = mntget(pfmfs_mnt); - file->f_mapping = inode->i_mapping; + file = alloc_file(pfmfs_mnt, dentry, FMODE_READ, &pfm_file_ops); + if (!file) { + dput(dentry); + return ERR_PTR(-ENFILE); + } - file->f_op = &pfm_file_ops; - file->f_mode = FMODE_READ; file->f_flags = O_RDONLY; - file->f_pos = 0; - - /* - * may have to delay until context is attached? - */ - fd_install(fd, file); - - /* - * the file structure we will use - */ - *cfile = file; - - return fd; -out: - if (file) put_filp(file); - put_unused_fd(fd); - return ret; -} - -static void -pfm_free_fd(int fd, struct file *file) -{ - struct files_struct *files = current->files; - struct fdtable *fdt; + file->private_data = ctx; - /* - * there ie no fd_uninstall(), so we do it here - */ - spin_lock(&files->file_lock); - fdt = files_fdtable(files); - rcu_assign_pointer(fdt->fd[fd], NULL); - spin_unlock(&files->file_lock); - - if (file) - put_filp(file); - put_unused_fd(fd); + return file; } static int @@ -2475,6 +2477,7 @@ pfm_setup_buffer_fmt(struct task_struct *task, struct file *filp, pfm_context_t /* link buffer format and context */ ctx->ctx_buf_fmt = fmt; + ctx->ctx_fl_is_sampling = 1; /* assume record() is defined */ /* * check if buffer format wants to use perfmon buffer allocation/mapping service @@ -2669,78 +2672,45 @@ pfm_context_create(pfm_context_t *ctx, void *arg, int count, struct pt_regs *reg { pfarg_context_t *req = (pfarg_context_t *)arg; struct file *filp; + struct path path; int ctx_flags; + int fd; int ret; /* let's check the arguments first */ ret = pfarg_is_sane(current, req); - if (ret < 0) return ret; + if (ret < 0) + return ret; ctx_flags = req->ctx_flags; ret = -ENOMEM; - ctx = pfm_context_alloc(); - if (!ctx) goto error; + fd = get_unused_fd(); + if (fd < 0) + return fd; - ret = pfm_alloc_fd(&filp); - if (ret < 0) goto error_file; + ctx = pfm_context_alloc(ctx_flags); + if (!ctx) + goto error; - req->ctx_fd = ctx->ctx_fd = ret; + filp = pfm_alloc_file(ctx); + if (IS_ERR(filp)) { + ret = PTR_ERR(filp); + goto error_file; + } - /* - * attach context to file - */ - filp->private_data = ctx; + req->ctx_fd = ctx->ctx_fd = fd; /* * does the user want to sample? */ if (pfm_uuid_cmp(req->ctx_smpl_buf_id, pfm_null_uuid)) { ret = pfm_setup_buffer_fmt(current, filp, ctx, ctx_flags, 0, req); - if (ret) goto buffer_error; + if (ret) + goto buffer_error; } - /* - * init context protection lock - */ - spin_lock_init(&ctx->ctx_lock); - - /* - * context is unloaded - */ - ctx->ctx_state = PFM_CTX_UNLOADED; - - /* - * initialization of context's flags - */ - ctx->ctx_fl_block = (ctx_flags & PFM_FL_NOTIFY_BLOCK) ? 1 : 0; - ctx->ctx_fl_system = (ctx_flags & PFM_FL_SYSTEM_WIDE) ? 1: 0; - ctx->ctx_fl_is_sampling = ctx->ctx_buf_fmt ? 1 : 0; /* assume record() is defined */ - ctx->ctx_fl_no_msg = (ctx_flags & PFM_FL_OVFL_NO_MSG) ? 1: 0; - /* - * will move to set properties - * ctx->ctx_fl_excl_idle = (ctx_flags & PFM_FL_EXCL_IDLE) ? 1: 0; - */ - - /* - * init restart semaphore to locked - */ - init_completion(&ctx->ctx_restart_done); - - /* - * activation is used in SMP only - */ - ctx->ctx_last_activation = PFM_INVALID_ACTIVATION; - SET_LAST_CPU(ctx, -1); - - /* - * initialize notification message queue - */ - ctx->ctx_msgq_head = ctx->ctx_msgq_tail = 0; - init_waitqueue_head(&ctx->ctx_msgq_wait); - init_waitqueue_head(&ctx->ctx_zombieq); - DPRINT(("ctx=%p flags=0x%x system=%d notify_block=%d excl_idle=%d no_msg=%d ctx_fd=%d \n", ctx, ctx_flags, @@ -2755,10 +2725,14 @@ pfm_context_create(pfm_context_t *ctx, void *arg, int count, struct pt_regs *reg */ pfm_reset_pmu_state(ctx); + fd_install(fd, filp); + return 0; buffer_error: - pfm_free_fd(ctx->ctx_fd, filp); + path = filp->f_path; + put_filp(filp); + path_put(&path); if (ctx->ctx_buf_fmt) { pfm_buf_fmt_exit(ctx->ctx_buf_fmt, current, NULL, regs); @@ -2767,6 +2741,7 @@ error_file: pfm_context_free(ctx); error: + put_unused_fd(fd); return ret; } -- cgit v1.2.3-70-g09d2