X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fs390%2Fappldata%2Fappldata_base.c;h=b8c2372902634c22db1f20162b966445ebf434a2;hb=97bf2856c6014879bd04983a3e9dfcdac1e7fe85;hp=0f8c08ad974abbe52d6331973b3d35e78ece7c45;hpb=9213980e6a70d8473e0ffd4b39ab5b6caaba9ff5;p=linux-2.6.git diff --git a/arch/s390/appldata/appldata_base.c b/arch/s390/appldata/appldata_base.c index 0f8c08ad9..b8c237290 100644 --- a/arch/s390/appldata/appldata_base.c +++ b/arch/s390/appldata/appldata_base.c @@ -5,26 +5,29 @@ * Exports appldata_register_ops() and appldata_unregister_ops() for the * data gathering modules. * - * Copyright (C) 2003 IBM Corporation, IBM Deutschland Entwicklung GmbH. + * Copyright (C) 2003,2006 IBM Corporation, IBM Deutschland Entwicklung GmbH. * - * Author: Gerald Schaefer + * Author: Gerald Schaefer */ -#include #include #include #include #include -#include -#include #include #include -#include +#include #include #include #include +#include +#include +#include +#include #include -//#include +#include +#include +#include #include "appldata.h" @@ -36,60 +39,16 @@ #define TOD_MICRO 0x01000 /* nr. of TOD clock units for 1 microsecond */ -#ifndef CONFIG_ARCH_S390X - -#define APPLDATA_START_INTERVAL_REC 0x00 /* Function codes for */ -#define APPLDATA_STOP_REC 0x01 /* DIAG 0xDC */ -#define APPLDATA_GEN_EVENT_RECORD 0x02 -#define APPLDATA_START_CONFIG_REC 0x03 - -#else - -#define APPLDATA_START_INTERVAL_REC 0x80 -#define APPLDATA_STOP_REC 0x81 -#define APPLDATA_GEN_EVENT_RECORD 0x82 -#define APPLDATA_START_CONFIG_REC 0x83 - -#endif /* CONFIG_ARCH_S390X */ - - -/* - * Parameter list for DIAGNOSE X'DC' - */ -#ifndef CONFIG_ARCH_S390X -struct appldata_parameter_list { - u16 diag; /* The DIAGNOSE code X'00DC' */ - u8 function; /* The function code for the DIAGNOSE */ - u8 parlist_length; /* Length of the parameter list */ - u32 product_id_addr; /* Address of the 16-byte product ID */ - u16 reserved; - u16 buffer_length; /* Length of the application data buffer */ - u32 buffer_addr; /* Address of the application data buffer */ -}; -#else -struct appldata_parameter_list { - u16 diag; - u8 function; - u8 parlist_length; - u32 unused01; - u16 reserved; - u16 buffer_length; - u32 unused02; - u64 product_id_addr; - u64 buffer_addr; -}; -#endif /* CONFIG_ARCH_S390X */ - /* * /proc entries (sysctl) */ static const char appldata_proc_name[APPLDATA_PROC_NAME_LENGTH] = "appldata"; static int appldata_timer_handler(ctl_table *ctl, int write, struct file *filp, - void __user *buffer, size_t *lenp); + void __user *buffer, size_t *lenp, loff_t *ppos); static int appldata_interval_handler(ctl_table *ctl, int write, struct file *filp, void __user *buffer, - size_t *lenp); + size_t *lenp, loff_t *ppos); static struct ctl_table_header *appldata_sysctl_header; static struct ctl_table appldata_table[] = { @@ -124,56 +83,55 @@ static struct ctl_table appldata_dir_table[] = { */ DEFINE_PER_CPU(struct vtimer_list, appldata_timer); static atomic_t appldata_expire_count = ATOMIC_INIT(0); -static struct appldata_mod_vtimer_args { - struct vtimer_list *timer; - u64 expires; -} appldata_mod_vtimer_args; -static spinlock_t appldata_timer_lock = SPIN_LOCK_UNLOCKED; +static DEFINE_SPINLOCK(appldata_timer_lock); static int appldata_interval = APPLDATA_CPU_INTERVAL; static int appldata_timer_active; /* - * Tasklet + * Work queue */ -static struct tasklet_struct appldata_tasklet_struct; +static struct workqueue_struct *appldata_wq; +static void appldata_work_fn(struct work_struct *work); +static DECLARE_WORK(appldata_work, appldata_work_fn); + /* * Ops list */ -static spinlock_t appldata_ops_lock = SPIN_LOCK_UNLOCKED; +static DEFINE_SPINLOCK(appldata_ops_lock); static LIST_HEAD(appldata_ops_list); -/************************* timer, tasklet, DIAG ******************************/ +/*************************** timer, work, DIAG *******************************/ /* * appldata_timer_function() * - * schedule tasklet and reschedule timer + * schedule work and reschedule timer */ -static void appldata_timer_function(unsigned long data, struct pt_regs *regs) +static void appldata_timer_function(unsigned long data) { P_DEBUG(" -= Timer =-\n"); - P_DEBUG("CPU: %i, expire: %i\n", smp_processor_id(), + P_DEBUG("CPU: %i, expire_count: %i\n", smp_processor_id(), atomic_read(&appldata_expire_count)); if (atomic_dec_and_test(&appldata_expire_count)) { atomic_set(&appldata_expire_count, num_online_cpus()); - tasklet_schedule((struct tasklet_struct *) data); + queue_work(appldata_wq, (struct work_struct *) data); } } /* - * appldata_tasklet_function() + * appldata_work_fn() * * call data gathering function for each (active) module */ -static void appldata_tasklet_function(unsigned long data) +static void appldata_work_fn(struct work_struct *work) { struct list_head *lh; struct appldata_ops *ops; int i; - P_DEBUG(" -= Tasklet =-\n"); + P_DEBUG(" -= Work Queue =-\n"); i = 0; spin_lock(&appldata_ops_lock); list_for_each(lh, &appldata_ops_list) { @@ -187,66 +145,103 @@ static void appldata_tasklet_function(unsigned long data) spin_unlock(&appldata_ops_lock); } +/* + * appldata_diag() + * + * prepare parameter list, issue DIAG 0xDC + */ +int appldata_diag(char record_nr, u16 function, unsigned long buffer, + u16 length, char *mod_lvl) +{ + struct appldata_product_id id = { + .prod_nr = {0xD3, 0xC9, 0xD5, 0xE4, + 0xE7, 0xD2, 0xD9}, /* "LINUXKR" */ + .prod_fn = 0xD5D3, /* "NL" */ + .version_nr = 0xF2F6, /* "26" */ + .release_nr = 0xF0F1, /* "01" */ + }; + + id.record_nr = record_nr; + id.mod_lvl = (mod_lvl[0]) << 8 | mod_lvl[1]; + return appldata_asm(&id, function, (void *) buffer, length); +} +/************************ timer, work, DIAG ****************************/ + + +/****************************** /proc stuff **********************************/ + /* * appldata_mod_vtimer_wrap() * * wrapper function for mod_virt_timer(), because smp_call_function_on() * accepts only one parameter. */ -static void appldata_mod_vtimer_wrap(void *p) { - struct appldata_mod_vtimer_args *args = p; +static void __appldata_mod_vtimer_wrap(void *p) { + struct { + struct vtimer_list *timer; + u64 expires; + } *args = p; mod_virt_timer(args->timer, args->expires); } +#define APPLDATA_ADD_TIMER 0 +#define APPLDATA_DEL_TIMER 1 +#define APPLDATA_MOD_TIMER 2 + /* - * appldata_diag() + * __appldata_vtimer_setup() * - * prepare parameter list, issue DIAG 0xDC + * Add, delete or modify virtual timers on all online cpus. + * The caller needs to get the appldata_timer_lock spinlock. */ -static int appldata_diag(char record_nr, u16 function, unsigned long buffer, - u16 length) +static void +__appldata_vtimer_setup(int cmd) { - unsigned long ry; - struct appldata_product_id { - char prod_nr[7]; /* product nr. */ - char prod_fn[2]; /* product function */ - char record_nr; /* record nr. */ - char version_nr[2]; /* version */ - char release_nr[2]; /* release */ - char mod_lvl[2]; /* modification lvl. */ - } appldata_product_id = { - /* all strings are EBCDIC, record_nr is byte */ - .prod_nr = {0xD3, 0xC9, 0xD5, 0xE4, - 0xE7, 0xD2, 0xD9}, /* "LINUXKR" */ - .prod_fn = {0xD5, 0xD3}, /* "NL" */ - .record_nr = record_nr, - .version_nr = {0xF2, 0xF6}, /* "26" */ - .release_nr = {0xF0, 0xF1}, /* "01" */ - .mod_lvl = {0xF0, 0xF0}, /* "00" */ - }; - struct appldata_parameter_list appldata_parameter_list = { - .diag = 0xDC, - .function = function, - .parlist_length = - sizeof(appldata_parameter_list), - .buffer_length = length, - .product_id_addr = - (unsigned long) &appldata_product_id, - .buffer_addr = virt_to_phys((void *) buffer) - }; + u64 per_cpu_interval; + int i; - if (!MACHINE_IS_VM) - return -ENOSYS; - ry = -1; - asm volatile( - "diag %1,%0,0xDC\n\t" - : "=d" (ry) : "d" (&(appldata_parameter_list)) : "cc"); - return (int) ry; + switch (cmd) { + case APPLDATA_ADD_TIMER: + if (appldata_timer_active) + break; + per_cpu_interval = (u64) (appldata_interval*1000 / + num_online_cpus()) * TOD_MICRO; + for_each_online_cpu(i) { + per_cpu(appldata_timer, i).expires = per_cpu_interval; + smp_call_function_on(add_virt_timer_periodic, + &per_cpu(appldata_timer, i), + 0, 1, i); + } + appldata_timer_active = 1; + P_INFO("Monitoring timer started.\n"); + break; + case APPLDATA_DEL_TIMER: + for_each_online_cpu(i) + del_virt_timer(&per_cpu(appldata_timer, i)); + if (!appldata_timer_active) + break; + appldata_timer_active = 0; + atomic_set(&appldata_expire_count, num_online_cpus()); + P_INFO("Monitoring timer stopped.\n"); + break; + case APPLDATA_MOD_TIMER: + per_cpu_interval = (u64) (appldata_interval*1000 / + num_online_cpus()) * TOD_MICRO; + if (!appldata_timer_active) + break; + for_each_online_cpu(i) { + struct { + struct vtimer_list *timer; + u64 expires; + } args; + args.timer = &per_cpu(appldata_timer, i); + args.expires = per_cpu_interval; + smp_call_function_on(__appldata_mod_vtimer_wrap, + &args, 0, 1, i); + } + } } -/********************** timer, tasklet, DIAG ***************************/ - -/****************************** /proc stuff **********************************/ /* * appldata_timer_handler() * @@ -254,13 +249,12 @@ static int appldata_diag(char record_nr, u16 function, unsigned long buffer, */ static int appldata_timer_handler(ctl_table *ctl, int write, struct file *filp, - void __user *buffer, size_t *lenp) + void __user *buffer, size_t *lenp, loff_t *ppos) { - int len, i; + int len; char buf[2]; - u64 per_cpu_interval; - if (!*lenp || filp->f_pos) { + if (!*lenp || *ppos) { *lenp = 0; return 0; } @@ -272,34 +266,18 @@ appldata_timer_handler(ctl_table *ctl, int write, struct file *filp, return -EFAULT; goto out; } - per_cpu_interval = (u64) (appldata_interval*1000 / - num_online_cpus()) * TOD_MICRO; len = *lenp; if (copy_from_user(buf, buffer, len > sizeof(buf) ? sizeof(buf) : len)) return -EFAULT; spin_lock(&appldata_timer_lock); - per_cpu_interval = (u64) (appldata_interval*1000 / - num_online_cpus()) * TOD_MICRO; - if ((buf[0] == '1') && (!appldata_timer_active)) { - for (i = 0; i < num_online_cpus(); i++) { - per_cpu(appldata_timer, i).expires = per_cpu_interval; - smp_call_function_on(add_virt_timer_periodic, - &per_cpu(appldata_timer, i), - 0, 1, i); - } - appldata_timer_active = 1; - P_INFO("Monitoring timer started.\n"); - } else if ((buf[0] == '0') && (appldata_timer_active)) { - for (i = 0; i < num_online_cpus(); i++) { - del_virt_timer(&per_cpu(appldata_timer, i)); - } - appldata_timer_active = 0; - P_INFO("Monitoring timer stopped.\n"); - } + if (buf[0] == '1') + __appldata_vtimer_setup(APPLDATA_ADD_TIMER); + else if (buf[0] == '0') + __appldata_vtimer_setup(APPLDATA_DEL_TIMER); spin_unlock(&appldata_timer_lock); out: *lenp = len; - filp->f_pos += len; + *ppos += len; return 0; } @@ -311,13 +289,12 @@ out: */ static int appldata_interval_handler(ctl_table *ctl, int write, struct file *filp, - void __user *buffer, size_t *lenp) + void __user *buffer, size_t *lenp, loff_t *ppos) { - int len, i, interval; + int len, interval; char buf[16]; - u64 per_cpu_interval; - if (!*lenp || filp->f_pos) { + if (!*lenp || *ppos) { *lenp = 0; return 0; } @@ -333,6 +310,7 @@ appldata_interval_handler(ctl_table *ctl, int write, struct file *filp, if (copy_from_user(buf, buffer, len > sizeof(buf) ? sizeof(buf) : len)) { return -EFAULT; } + interval = 0; sscanf(buf, "%i", &interval); if (interval <= 0) { P_ERROR("Timer CPU interval has to be > 0!\n"); @@ -340,27 +318,15 @@ appldata_interval_handler(ctl_table *ctl, int write, struct file *filp, } spin_lock(&appldata_timer_lock); - per_cpu_interval = (u64) (interval*1000 / num_online_cpus()) * TOD_MICRO; appldata_interval = interval; - if (appldata_timer_active) { - for (i = 0; i < num_online_cpus(); i++) { - appldata_mod_vtimer_args.timer = - &per_cpu(appldata_timer, i); - appldata_mod_vtimer_args.expires = - per_cpu_interval; - smp_call_function_on( - appldata_mod_vtimer_wrap, - &appldata_mod_vtimer_args, - 0, 1, i); - } - } + __appldata_vtimer_setup(APPLDATA_MOD_TIMER); spin_unlock(&appldata_timer_lock); P_INFO("Monitoring CPU interval set to %u milliseconds.\n", interval); out: *lenp = len; - filp->f_pos += len; + *ppos += len; return 0; } @@ -372,7 +338,7 @@ out: */ static int appldata_generic_handler(ctl_table *ctl, int write, struct file *filp, - void __user *buffer, size_t *lenp) + void __user *buffer, size_t *lenp, loff_t *ppos) { struct appldata_ops *ops = NULL, *tmp_ops; int rc, len, found; @@ -380,7 +346,7 @@ appldata_generic_handler(ctl_table *ctl, int write, struct file *filp, struct list_head *lh; found = 0; - spin_lock_bh(&appldata_ops_lock); + spin_lock(&appldata_ops_lock); list_for_each(lh, &appldata_ops_list) { tmp_ops = list_entry(lh, struct appldata_ops, list); if (&tmp_ops->ctl_table[2] == ctl) { @@ -388,17 +354,17 @@ appldata_generic_handler(ctl_table *ctl, int write, struct file *filp, } } if (!found) { - spin_unlock_bh(&appldata_ops_lock); + spin_unlock(&appldata_ops_lock); return -ENODEV; } ops = ctl->data; if (!try_module_get(ops->owner)) { // protect this function - spin_unlock_bh(&appldata_ops_lock); + spin_unlock(&appldata_ops_lock); return -ENODEV; } - spin_unlock_bh(&appldata_ops_lock); + spin_unlock(&appldata_ops_lock); - if (!*lenp || filp->f_pos) { + if (!*lenp || *ppos) { *lenp = 0; module_put(ops->owner); return 0; @@ -420,31 +386,33 @@ appldata_generic_handler(ctl_table *ctl, int write, struct file *filp, return -EFAULT; } - spin_lock_bh(&appldata_ops_lock); + spin_lock(&appldata_ops_lock); if ((buf[0] == '1') && (ops->active == 0)) { - if (!try_module_get(ops->owner)) { // protect tasklet - spin_unlock_bh(&appldata_ops_lock); + // protect work queue callback + if (!try_module_get(ops->owner)) { + spin_unlock(&appldata_ops_lock); module_put(ops->owner); return -ENODEV; } - ops->active = 1; ops->callback(ops->data); // init record rc = appldata_diag(ops->record_nr, APPLDATA_START_INTERVAL_REC, - (unsigned long) ops->data, ops->size); + (unsigned long) ops->data, ops->size, + ops->mod_lvl); if (rc != 0) { P_ERROR("START DIAG 0xDC for %s failed, " "return code: %d\n", ops->name, rc); module_put(ops->owner); - ops->active = 0; } else { P_INFO("Monitoring %s data enabled, " "DIAG 0xDC started.\n", ops->name); + ops->active = 1; } } else if ((buf[0] == '0') && (ops->active == 1)) { ops->active = 0; rc = appldata_diag(ops->record_nr, APPLDATA_STOP_REC, - (unsigned long) ops->data, ops->size); + (unsigned long) ops->data, ops->size, + ops->mod_lvl); if (rc != 0) { P_ERROR("STOP DIAG 0xDC for %s failed, " "return code: %d\n", ops->name, rc); @@ -454,10 +422,10 @@ appldata_generic_handler(ctl_table *ctl, int write, struct file *filp, } module_put(ops->owner); } - spin_unlock_bh(&appldata_ops_lock); + spin_unlock(&appldata_ops_lock); out: *lenp = len; - filp->f_pos += len; + *ppos += len; module_put(ops->owner); return 0; } @@ -491,14 +459,13 @@ int appldata_register_ops(struct appldata_ops *ops) P_ERROR("ctl_nr %i already in use!\n", ops->ctl_nr); return -EBUSY; } - ops->ctl_table = kmalloc(4*sizeof(struct ctl_table), GFP_KERNEL); + ops->ctl_table = kzalloc(4*sizeof(struct ctl_table), GFP_KERNEL); if (ops->ctl_table == NULL) { P_ERROR("Not enough memory for %s ctl_table!\n", ops->name); return -ENOMEM; } - memset(ops->ctl_table, 0, 4*sizeof(struct ctl_table)); - spin_lock_bh(&appldata_ops_lock); + spin_lock(&appldata_ops_lock); list_for_each(lh, &appldata_ops_list) { tmp_ops = list_entry(lh, struct appldata_ops, list); P_DEBUG("register_ops loop: %i) name = %s, ctl = %i\n", @@ -510,18 +477,18 @@ int appldata_register_ops(struct appldata_ops *ops) APPLDATA_PROC_NAME_LENGTH) == 0) { P_ERROR("Name \"%s\" already registered!\n", ops->name); kfree(ops->ctl_table); - spin_unlock_bh(&appldata_ops_lock); + spin_unlock(&appldata_ops_lock); return -EBUSY; } if (tmp_ops->ctl_nr == ops->ctl_nr) { P_ERROR("ctl_nr %i already registered!\n", ops->ctl_nr); kfree(ops->ctl_table); - spin_unlock_bh(&appldata_ops_lock); + spin_unlock(&appldata_ops_lock); return -EBUSY; } } list_add(&ops->list, &appldata_ops_list); - spin_unlock_bh(&appldata_ops_lock); + spin_unlock(&appldata_ops_lock); ops->ctl_table[0].ctl_name = CTL_APPLDATA; ops->ctl_table[0].procname = appldata_proc_name; @@ -552,22 +519,73 @@ int appldata_register_ops(struct appldata_ops *ops) */ void appldata_unregister_ops(struct appldata_ops *ops) { - spin_lock_bh(&appldata_ops_lock); - unregister_sysctl_table(ops->sysctl_header); + void *table; + spin_lock(&appldata_ops_lock); list_del(&ops->list); - kfree(ops->ctl_table); + /* at that point any incoming access will fail */ + table = ops->ctl_table; ops->ctl_table = NULL; - spin_unlock_bh(&appldata_ops_lock); + spin_unlock(&appldata_ops_lock); + unregister_sysctl_table(ops->sysctl_header); + kfree(table); P_INFO("%s-ops unregistered!\n", ops->name); } /********************** module-ops management **************************/ /******************************* init / exit *********************************/ + +static void +appldata_online_cpu(int cpu) +{ + init_virt_timer(&per_cpu(appldata_timer, cpu)); + per_cpu(appldata_timer, cpu).function = appldata_timer_function; + per_cpu(appldata_timer, cpu).data = (unsigned long) + &appldata_work; + atomic_inc(&appldata_expire_count); + spin_lock(&appldata_timer_lock); + __appldata_vtimer_setup(APPLDATA_MOD_TIMER); + spin_unlock(&appldata_timer_lock); +} + +static void +appldata_offline_cpu(int cpu) +{ + del_virt_timer(&per_cpu(appldata_timer, cpu)); + if (atomic_dec_and_test(&appldata_expire_count)) { + atomic_set(&appldata_expire_count, num_online_cpus()); + queue_work(appldata_wq, &appldata_work); + } + spin_lock(&appldata_timer_lock); + __appldata_vtimer_setup(APPLDATA_MOD_TIMER); + spin_unlock(&appldata_timer_lock); +} + +static int __cpuinit +appldata_cpu_notify(struct notifier_block *self, + unsigned long action, void *hcpu) +{ + switch (action) { + case CPU_ONLINE: + appldata_online_cpu((long) hcpu); + break; + case CPU_DEAD: + appldata_offline_cpu((long) hcpu); + break; + default: + break; + } + return NOTIFY_OK; +} + +static struct notifier_block appldata_nb = { + .notifier_call = appldata_cpu_notify, +}; + /* * appldata_init() * - * init timer and tasklet, register /proc entries + * init timer, register /proc entries */ static int __init appldata_init(void) { @@ -576,13 +594,17 @@ static int __init appldata_init(void) P_DEBUG("sizeof(parameter_list) = %lu\n", sizeof(struct appldata_parameter_list)); - for (i = 0; i < num_online_cpus(); i++) { - init_virt_timer(&per_cpu(appldata_timer, i)); - per_cpu(appldata_timer, i).function = appldata_timer_function; - per_cpu(appldata_timer, i).data = (unsigned long) - &appldata_tasklet_struct; + appldata_wq = create_singlethread_workqueue("appldata"); + if (!appldata_wq) { + P_ERROR("Could not create work queue\n"); + return -ENOMEM; } - atomic_set(&appldata_expire_count, num_online_cpus()); + + for_each_online_cpu(i) + appldata_online_cpu(i); + + /* Register cpu hotplug notifier */ + register_hotcpu_notifier(&appldata_nb); appldata_sysctl_header = register_sysctl_table(appldata_dir_table, 1); #ifdef MODULE @@ -591,7 +613,6 @@ static int __init appldata_init(void) appldata_table[1].de->owner = THIS_MODULE; #endif - tasklet_init(&appldata_tasklet_struct, appldata_tasklet_function, 0); P_DEBUG("Base interface initialized.\n"); return 0; } @@ -599,7 +620,7 @@ static int __init appldata_init(void) /* * appldata_exit() * - * stop timer and tasklet, unregister /proc entries + * stop timer, unregister /proc entries */ static void __exit appldata_exit(void) { @@ -611,26 +632,27 @@ static void __exit appldata_exit(void) /* * ops list should be empty, but just in case something went wrong... */ - spin_lock_bh(&appldata_ops_lock); + spin_lock(&appldata_ops_lock); list_for_each(lh, &appldata_ops_list) { ops = list_entry(lh, struct appldata_ops, list); rc = appldata_diag(ops->record_nr, APPLDATA_STOP_REC, - (unsigned long) ops->data, ops->size); + (unsigned long) ops->data, ops->size, + ops->mod_lvl); if (rc != 0) { P_ERROR("STOP DIAG 0xDC for %s failed, " "return code: %d\n", ops->name, rc); } } - spin_unlock_bh(&appldata_ops_lock); + spin_unlock(&appldata_ops_lock); + + for_each_online_cpu(i) + appldata_offline_cpu(i); - for (i = 0; i < num_online_cpus(); i++) { - del_virt_timer(&per_cpu(appldata_timer, i)); - } appldata_timer_active = 0; unregister_sysctl_table(appldata_sysctl_header); - tasklet_kill(&appldata_tasklet_struct); + destroy_workqueue(appldata_wq); P_DEBUG("... module unloaded!\n"); } /**************************** init / exit ******************************/ @@ -644,6 +666,7 @@ MODULE_DESCRIPTION("Linux-VM Monitor Stream, base infrastructure"); EXPORT_SYMBOL_GPL(appldata_register_ops); EXPORT_SYMBOL_GPL(appldata_unregister_ops); +EXPORT_SYMBOL_GPL(appldata_diag); #ifdef MODULE /* @@ -684,8 +707,6 @@ unsigned long nr_iowait(void) #endif /* MODULE */ EXPORT_SYMBOL_GPL(si_swapinfo); EXPORT_SYMBOL_GPL(nr_threads); -EXPORT_SYMBOL_GPL(avenrun); -EXPORT_SYMBOL_GPL(get_full_page_state); EXPORT_SYMBOL_GPL(nr_running); EXPORT_SYMBOL_GPL(nr_iowait); //EXPORT_SYMBOL_GPL(nr_context_switches);