diff options
Diffstat (limited to 'arch/ia64/kernel')
-rw-r--r-- | arch/ia64/kernel/acpi.c | 2 | ||||
-rw-r--r-- | arch/ia64/kernel/asm-offsets.c | 7 | ||||
-rw-r--r-- | arch/ia64/kernel/irq.c | 4 | ||||
-rw-r--r-- | arch/ia64/kernel/palinfo.c | 2 | ||||
-rw-r--r-- | arch/ia64/kernel/perfmon.c | 205 | ||||
-rw-r--r-- | arch/ia64/kernel/process.c | 2 | ||||
-rw-r--r-- | arch/ia64/kernel/salinfo.c | 10 | ||||
-rw-r--r-- | arch/ia64/kernel/signal.c | 15 | ||||
-rw-r--r-- | arch/ia64/kernel/smp.c | 68 | ||||
-rw-r--r-- | arch/ia64/kernel/smpboot.c | 12 | ||||
-rw-r--r-- | arch/ia64/kernel/time.c | 5 | ||||
-rw-r--r-- | arch/ia64/kernel/topology.c | 25 | ||||
-rw-r--r-- | arch/ia64/kernel/uncached.c | 23 |
13 files changed, 182 insertions, 198 deletions
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; diff --git a/arch/ia64/kernel/asm-offsets.c b/arch/ia64/kernel/asm-offsets.c index 230a6f92367..c64a55af9b9 100644 --- a/arch/ia64/kernel/asm-offsets.c +++ b/arch/ia64/kernel/asm-offsets.c @@ -9,7 +9,7 @@ #include <linux/sched.h> #include <linux/pid.h> #include <linux/clocksource.h> - +#include <linux/kbuild.h> #include <asm-ia64/processor.h> #include <asm-ia64/ptrace.h> #include <asm-ia64/siginfo.h> @@ -19,11 +19,6 @@ #include "../kernel/sigframe.h" #include "../kernel/fsyscall_gtod_data.h" -#define DEFINE(sym, val) \ - asm volatile("\n->" #sym " %0 " #val : : "i" (val)) - -#define BLANK() asm volatile("\n->" : : ) - void foo(void) { DEFINE(IA64_TASK_SIZE, sizeof (struct task_struct)); 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/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, diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c index c8e403752a0..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; } @@ -6695,16 +6670,12 @@ pfm_init(void) /* * create /proc/perfmon (mostly for debugging purposes) */ - perfmon_dir = create_proc_entry("perfmon", S_IRUGO, NULL); + perfmon_dir = proc_create("perfmon", S_IRUGO, NULL, &pfm_proc_fops); if (perfmon_dir == NULL) { printk(KERN_ERR "perfmon: cannot create /proc entry, perfmon disabled\n"); pmu_conf = NULL; return -1; } - /* - * install customized file operations for /proc/perfmon entry - */ - perfmon_dir->proc_fops = &pfm_proc_fops; /* * create /proc/sys/kernel/perfmon (for debugging purposes) diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c index a5ea817cbcb..58dcfac5ea8 100644 --- a/arch/ia64/kernel/process.c +++ b/arch/ia64/kernel/process.c @@ -183,7 +183,7 @@ do_notify_resume_user (sigset_t *unused, struct sigscratch *scr, long in_syscall #endif /* deal with pending signal delivery */ - if (test_thread_flag(TIF_SIGPENDING)||test_thread_flag(TIF_RESTORE_SIGMASK)) + if (test_thread_flag(TIF_SIGPENDING)) ia64_do_signal(scr, in_syscall); /* copy user rbs to kernel rbs */ diff --git a/arch/ia64/kernel/salinfo.c b/arch/ia64/kernel/salinfo.c index b11bb50a197..ecb9eb78d68 100644 --- a/arch/ia64/kernel/salinfo.c +++ b/arch/ia64/kernel/salinfo.c @@ -648,18 +648,16 @@ salinfo_init(void) if (!dir) continue; - entry = create_proc_entry("event", S_IRUSR, dir); + entry = proc_create_data("event", S_IRUSR, dir, + &salinfo_event_fops, data); if (!entry) continue; - entry->data = data; - entry->proc_fops = &salinfo_event_fops; *sdir++ = entry; - entry = create_proc_entry("data", S_IRUSR | S_IWUSR, dir); + entry = proc_create_data("data", S_IRUSR | S_IWUSR, dir, + &salinfo_data_fops, data); if (!entry) continue; - entry->data = data; - entry->proc_fops = &salinfo_data_fops; *sdir++ = entry; /* we missed any events before now */ 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/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); diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c index 16483be18c0..d7ad42b77d4 100644 --- a/arch/ia64/kernel/smpboot.c +++ b/arch/ia64/kernel/smpboot.c @@ -873,7 +873,8 @@ identify_siblings(struct cpuinfo_ia64 *c) u16 pltid; pal_logical_to_physical_t info; - if ((status = ia64_pal_logical_to_phys(-1, &info)) != PAL_STATUS_SUCCESS) { + status = ia64_pal_logical_to_phys(-1, &info); + if (status != PAL_STATUS_SUCCESS) { if (status != PAL_STATUS_UNIMPLEMENTED) { printk(KERN_ERR "ia64_pal_logical_to_phys failed with %ld\n", @@ -885,8 +886,13 @@ identify_siblings(struct cpuinfo_ia64 *c) info.overview_cpp = 1; info.overview_tpc = 1; } - if ((status = ia64_sal_physical_id_info(&pltid)) != PAL_STATUS_SUCCESS) { - printk(KERN_ERR "ia64_sal_pltid failed with %ld\n", status); + + status = ia64_sal_physical_id_info(&pltid); + if (status != PAL_STATUS_SUCCESS) { + if (status != PAL_STATUS_UNIMPLEMENTED) + printk(KERN_ERR + "ia64_sal_pltid failed with %ld\n", + status); return; } 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) { diff --git a/arch/ia64/kernel/topology.c b/arch/ia64/kernel/topology.c index a2484fc1a06..26228e2d01a 100644 --- a/arch/ia64/kernel/topology.c +++ b/arch/ia64/kernel/topology.c @@ -27,9 +27,20 @@ static struct ia64_cpu *sysfs_cpus; -int arch_register_cpu(int num) +void arch_fix_phys_package_id(int num, u32 slot) { -#if defined (CONFIG_ACPI) && defined (CONFIG_HOTPLUG_CPU) +#ifdef CONFIG_SMP + if (cpu_data(num)->socket_id == -1) + cpu_data(num)->socket_id = slot; +#endif +} +EXPORT_SYMBOL_GPL(arch_fix_phys_package_id); + + +#ifdef CONFIG_HOTPLUG_CPU +int __ref arch_register_cpu(int num) +{ +#ifdef CONFIG_ACPI /* * If CPEI can be re-targetted or if this is not * CPEI target, then it is hotpluggable @@ -38,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/arch/ia64/kernel/uncached.c b/arch/ia64/kernel/uncached.c index 2a90c32024f..e77995a6e3e 100644 --- a/arch/ia64/kernel/uncached.c +++ b/arch/ia64/kernel/uncached.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2001-2006 Silicon Graphics, Inc. All rights reserved. + * Copyright (C) 2001-2008 Silicon Graphics, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License @@ -177,12 +177,13 @@ failed: * uncached_alloc_page * * @starting_nid: node id of node to start with, or -1 + * @n_pages: number of contiguous pages to allocate * - * Allocate 1 uncached page. Allocates on the requested node. If no - * uncached pages are available on the requested node, roundrobin starting - * with the next higher node. + * Allocate the specified number of contiguous uncached pages on the + * the requested node. If not enough contiguous uncached pages are available + * on the requested node, roundrobin starting with the next higher node. */ -unsigned long uncached_alloc_page(int starting_nid) +unsigned long uncached_alloc_page(int starting_nid, int n_pages) { unsigned long uc_addr; struct uncached_pool *uc_pool; @@ -202,7 +203,8 @@ unsigned long uncached_alloc_page(int starting_nid) if (uc_pool->pool == NULL) continue; do { - uc_addr = gen_pool_alloc(uc_pool->pool, PAGE_SIZE); + uc_addr = gen_pool_alloc(uc_pool->pool, + n_pages * PAGE_SIZE); if (uc_addr != 0) return uc_addr; } while (uncached_add_chunk(uc_pool, nid) == 0); @@ -217,11 +219,12 @@ EXPORT_SYMBOL(uncached_alloc_page); /* * uncached_free_page * - * @uc_addr: uncached address of page to free + * @uc_addr: uncached address of first page to free + * @n_pages: number of contiguous pages to free * - * Free a single uncached page. + * Free the specified number of uncached pages. */ -void uncached_free_page(unsigned long uc_addr) +void uncached_free_page(unsigned long uc_addr, int n_pages) { int nid = paddr_to_nid(uc_addr - __IA64_UNCACHED_OFFSET); struct gen_pool *pool = uncached_pools[nid].pool; @@ -232,7 +235,7 @@ void uncached_free_page(unsigned long uc_addr) if ((uc_addr & (0XFUL << 60)) != __IA64_UNCACHED_OFFSET) panic("uncached_free_page invalid address %lx\n", uc_addr); - gen_pool_free(pool, uc_addr, PAGE_SIZE); + gen_pool_free(pool, uc_addr, n_pages * PAGE_SIZE); } EXPORT_SYMBOL(uncached_free_page); |