aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/dontdiff2
-rw-r--r--Documentation/kbuild/kconfig-language.txt17
-rw-r--r--Documentation/vm/slabinfo.c27
-rw-r--r--Makefile27
-rw-r--r--arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c10
-rw-r--r--arch/x86/kernel/vmlinux_64.lds.S6
-rw-r--r--arch/x86/vdso/vdso.S10
-rw-r--r--drivers/acpi/processor_thermal.c30
-rw-r--r--drivers/atm/nicstar.c2
-rw-r--r--drivers/char/drm/r128_cce.c2
-rw-r--r--drivers/char/tty_io.c2
-rw-r--r--drivers/cpufreq/cpufreq.c129
-rw-r--r--drivers/cpufreq/cpufreq_stats.c6
-rw-r--r--include/linux/mm_types.h5
-rw-r--r--include/linux/slub_def.h16
-rw-r--r--init/do_mounts_md.c2
-rw-r--r--init/do_mounts_rd.c2
-rw-r--r--kernel/cpuset.c3
-rw-r--r--kernel/hrtimer.c19
-rw-r--r--kernel/pid_namespace.c2
-rw-r--r--kernel/ptrace.c7
-rw-r--r--mm/hugetlb.c2
-rw-r--r--mm/memory_hotplug.c2
-rw-r--r--mm/slob.c3
-rw-r--r--mm/slub.c481
-rw-r--r--scripts/gen_initramfs_list.sh2
-rw-r--r--scripts/kconfig/lex.zconf.c_shipped25
-rw-r--r--scripts/kconfig/lkc_proto.h2
-rw-r--r--scripts/kconfig/lxdialog/inputbox.c2
-rw-r--r--scripts/kconfig/menu.c64
-rw-r--r--scripts/kconfig/symbol.c118
-rw-r--r--scripts/kconfig/zconf.tab.c_shipped301
-rw-r--r--scripts/kconfig/zconf.y13
33 files changed, 764 insertions, 577 deletions
diff --git a/Documentation/dontdiff b/Documentation/dontdiff
index 354aec047c0..881e6dd03ae 100644
--- a/Documentation/dontdiff
+++ b/Documentation/dontdiff
@@ -141,6 +141,7 @@ mkprep
mktables
mktree
modpost
+modules.order
modversions.h*
offset.h
offsets.h
@@ -171,6 +172,7 @@ sm_tbl*
split-include
tags
tftpboot.img
+timeconst.h
times.h*
tkparse
trix_boot.h
diff --git a/Documentation/kbuild/kconfig-language.txt b/Documentation/kbuild/kconfig-language.txt
index 649cb879989..00b950d1c19 100644
--- a/Documentation/kbuild/kconfig-language.txt
+++ b/Documentation/kbuild/kconfig-language.txt
@@ -104,14 +104,15 @@ applicable everywhere (see syntax).
Reverse dependencies can only be used with boolean or tristate
symbols.
Note:
- select is evil.... select will by brute force set a symbol
- equal to 'y' without visiting the dependencies. So abusing
- select you are able to select a symbol FOO even if FOO depends
- on BAR that is not set. In general use select only for
- non-visible symbols (no prompts anywhere) and for symbols with
- no dependencies. That will limit the usefulness but on the
- other hand avoid the illegal configurations all over. kconfig
- should one day warn about such things.
+ select should be used with care. select will force
+ a symbol to a value without visiting the dependencies.
+ By abusing select you are able to select a symbol FOO even
+ if FOO depends on BAR that is not set.
+ In general use select only for non-visible symbols
+ (no prompts anywhere) and for symbols with no dependencies.
+ That will limit the usefulness but on the other hand avoid
+ the illegal configurations all over.
+ kconfig should one day warn about such things.
- numerical ranges: "range" <symbol> <symbol> ["if" <expr>]
This allows to limit the range of possible input values for int
diff --git a/Documentation/vm/slabinfo.c b/Documentation/vm/slabinfo.c
index 22d7e3e4d60..d3ce295bffa 100644
--- a/Documentation/vm/slabinfo.c
+++ b/Documentation/vm/slabinfo.c
@@ -31,7 +31,7 @@ struct slabinfo {
int hwcache_align, object_size, objs_per_slab;
int sanity_checks, slab_size, store_user, trace;
int order, poison, reclaim_account, red_zone;
- unsigned long partial, objects, slabs;
+ unsigned long partial, objects, slabs, objects_partial, objects_total;
unsigned long alloc_fastpath, alloc_slowpath;
unsigned long free_fastpath, free_slowpath;
unsigned long free_frozen, free_add_partial, free_remove_partial;
@@ -540,7 +540,8 @@ void slabcache(struct slabinfo *s)
return;
store_size(size_str, slab_size(s));
- snprintf(dist_str, 40, "%lu/%lu/%d", s->slabs, s->partial, s->cpu_slabs);
+ snprintf(dist_str, 40, "%lu/%lu/%d", s->slabs - s->cpu_slabs,
+ s->partial, s->cpu_slabs);
if (!line++)
first_line();
@@ -776,7 +777,6 @@ void totals(void)
unsigned long used;
unsigned long long wasted;
unsigned long long objwaste;
- long long objects_in_partial_slabs;
unsigned long percentage_partial_slabs;
unsigned long percentage_partial_objs;
@@ -790,18 +790,11 @@ void totals(void)
wasted = size - used;
objwaste = s->slab_size - s->object_size;
- objects_in_partial_slabs = s->objects -
- (s->slabs - s->partial - s ->cpu_slabs) *
- s->objs_per_slab;
-
- if (objects_in_partial_slabs < 0)
- objects_in_partial_slabs = 0;
-
percentage_partial_slabs = s->partial * 100 / s->slabs;
if (percentage_partial_slabs > 100)
percentage_partial_slabs = 100;
- percentage_partial_objs = objects_in_partial_slabs * 100
+ percentage_partial_objs = s->objects_partial * 100
/ s->objects;
if (percentage_partial_objs > 100)
@@ -823,8 +816,8 @@ void totals(void)
min_objects = s->objects;
if (used < min_used)
min_used = used;
- if (objects_in_partial_slabs < min_partobj)
- min_partobj = objects_in_partial_slabs;
+ if (s->objects_partial < min_partobj)
+ min_partobj = s->objects_partial;
if (percentage_partial_slabs < min_ppart)
min_ppart = percentage_partial_slabs;
if (percentage_partial_objs < min_ppartobj)
@@ -848,8 +841,8 @@ void totals(void)
max_objects = s->objects;
if (used > max_used)
max_used = used;
- if (objects_in_partial_slabs > max_partobj)
- max_partobj = objects_in_partial_slabs;
+ if (s->objects_partial > max_partobj)
+ max_partobj = s->objects_partial;
if (percentage_partial_slabs > max_ppart)
max_ppart = percentage_partial_slabs;
if (percentage_partial_objs > max_ppartobj)
@@ -864,7 +857,7 @@ void totals(void)
total_objects += s->objects;
total_used += used;
- total_partobj += objects_in_partial_slabs;
+ total_partobj += s->objects_partial;
total_ppart += percentage_partial_slabs;
total_ppartobj += percentage_partial_objs;
@@ -1160,6 +1153,8 @@ void read_slab_dir(void)
slab->hwcache_align = get_obj("hwcache_align");
slab->object_size = get_obj("object_size");
slab->objects = get_obj("objects");
+ slab->objects_partial = get_obj("objects_partial");
+ slab->objects_total = get_obj("objects_total");
slab->objs_per_slab = get_obj("objs_per_slab");
slab->order = get_obj("order");
slab->partial = get_obj("partial");
diff --git a/Makefile b/Makefile
index fc3411e6f07..d3634cd6fe3 100644
--- a/Makefile
+++ b/Makefile
@@ -1174,8 +1174,10 @@ rpm: include/config/kernel.release FORCE
# Brief documentation of the typical targets used
# ---------------------------------------------------------------------------
-boards := $(wildcard $(srctree)/arch/$(ARCH)/configs/*_defconfig)
+boards := $(wildcard $(srctree)/arch/$(SRCARCH)/configs/*_defconfig)
boards := $(notdir $(boards))
+board-dirs := $(dir $(wildcard $(srctree)/arch/$(SRCARCH)/configs/*/*_defconfig))
+board-dirs := $(sort $(notdir $(board-dirs:/=)))
help:
@echo 'Cleaning targets:'
@@ -1221,14 +1223,19 @@ help:
@echo 'Documentation targets:'
@$(MAKE) -f $(srctree)/Documentation/DocBook/Makefile dochelp
@echo ''
- @echo 'Architecture specific targets ($(ARCH)):'
+ @echo 'Architecture specific targets ($(SRCARCH)):'
@$(if $(archhelp),$(archhelp),\
- echo ' No architecture specific help defined for $(ARCH)')
+ echo ' No architecture specific help defined for $(SRCARCH)')
@echo ''
@$(if $(boards), \
$(foreach b, $(boards), \
printf " %-24s - Build for %s\\n" $(b) $(subst _defconfig,,$(b));) \
echo '')
+ @$(if $(board-dirs), \
+ $(foreach b, $(board-dirs), \
+ printf " %-16s - Show %s-specific targets\\n" help-$(b) $(b);) \
+ printf " %-16s - Show all of the above\\n" help-boards; \
+ echo '')
@echo ' make V=0|1 [targets] 0 => quiet build (default), 1 => verbose build'
@echo ' make V=2 [targets] 2 => give reason for rebuild of target'
@@ -1240,6 +1247,20 @@ help:
@echo 'For further info see the ./README file'
+help-board-dirs := $(addprefix help-,$(board-dirs))
+
+help-boards: $(help-board-dirs)
+
+boards-per-dir = $(notdir $(wildcard $(srctree)/arch/$(SRCARCH)/configs/$*/*_defconfig))
+
+$(help-board-dirs): help-%:
+ @echo 'Architecture specific targets ($(SRCARCH) $*):'
+ @$(if $(boards-per-dir), \
+ $(foreach b, $(boards-per-dir), \
+ printf " %-24s - Build for %s\\n" $*/$(b) $(subst _defconfig,,$(b));) \
+ echo '')
+
+
# Documentation targets
# ---------------------------------------------------------------------------
%docs: scripts_basic FORCE
diff --git a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
index e2d870de837..8db8f73503b 100644
--- a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
+++ b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
@@ -339,6 +339,7 @@ static unsigned int get_cur_freq_on_cpu(unsigned int cpu)
{
struct acpi_cpufreq_data *data = per_cpu(drv_data, cpu);
unsigned int freq;
+ unsigned int cached_freq;
dprintk("get_cur_freq_on_cpu (%d)\n", cpu);
@@ -347,7 +348,16 @@ static unsigned int get_cur_freq_on_cpu(unsigned int cpu)
return 0;
}
+ cached_freq = data->freq_table[data->acpi_data->state].frequency;
freq = extract_freq(get_cur_val(&cpumask_of_cpu(cpu)), data);
+ if (freq != cached_freq) {
+ /*
+ * The dreaded BIOS frequency change behind our back.
+ * Force set the frequency on next target call.
+ */
+ data->resume = 1;
+ }
+
dprintk("cur freq = %u\n", freq);
return freq;
diff --git a/arch/x86/kernel/vmlinux_64.lds.S b/arch/x86/kernel/vmlinux_64.lds.S
index b7ab3c335fa..fad3674b06a 100644
--- a/arch/x86/kernel/vmlinux_64.lds.S
+++ b/arch/x86/kernel/vmlinux_64.lds.S
@@ -209,12 +209,6 @@ SECTIONS
EXIT_DATA
}
-/* vdso blob that is mapped into user space */
- vdso_start = . ;
- .vdso : AT(ADDR(.vdso) - LOAD_OFFSET) { *(.vdso) }
- . = ALIGN(PAGE_SIZE);
- vdso_end = .;
-
#ifdef CONFIG_BLK_DEV_INITRD
. = ALIGN(PAGE_SIZE);
__initramfs_start = .;
diff --git a/arch/x86/vdso/vdso.S b/arch/x86/vdso/vdso.S
index 4b1620a1529..1d3aa6b8718 100644
--- a/arch/x86/vdso/vdso.S
+++ b/arch/x86/vdso/vdso.S
@@ -1,2 +1,10 @@
- .section ".vdso","a"
+#include <linux/init.h>
+
+__INITDATA
+
+ .globl vdso_start, vdso_end
+vdso_start:
.incbin "arch/x86/vdso/vdso.so"
+vdso_end:
+
+__FINIT
diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c
index 9cb43f52f7b..649ae99b921 100644
--- a/drivers/acpi/processor_thermal.c
+++ b/drivers/acpi/processor_thermal.c
@@ -97,7 +97,7 @@ static int acpi_processor_apply_limit(struct acpi_processor *pr)
#define CPUFREQ_THERMAL_MIN_STEP 0
#define CPUFREQ_THERMAL_MAX_STEP 3
-static unsigned int cpufreq_thermal_reduction_pctg[NR_CPUS];
+static DEFINE_PER_CPU(unsigned int, cpufreq_thermal_reduction_pctg);
static unsigned int acpi_thermal_cpufreq_is_init = 0;
static int cpu_has_cpufreq(unsigned int cpu)
@@ -113,9 +113,9 @@ static int acpi_thermal_cpufreq_increase(unsigned int cpu)
if (!cpu_has_cpufreq(cpu))
return -ENODEV;
- if (cpufreq_thermal_reduction_pctg[cpu] <
+ if (per_cpu(cpufreq_thermal_reduction_pctg, cpu) <
CPUFREQ_THERMAL_MAX_STEP) {
- cpufreq_thermal_reduction_pctg[cpu]++;
+ per_cpu(cpufreq_thermal_reduction_pctg, cpu)++;
cpufreq_update_policy(cpu);
return 0;
}
@@ -128,14 +128,14 @@ static int acpi_thermal_cpufreq_decrease(unsigned int cpu)
if (!cpu_has_cpufreq(cpu))
return -ENODEV;
- if (cpufreq_thermal_reduction_pctg[cpu] >
+ if (per_cpu(cpufreq_thermal_reduction_pctg, cpu) >
(CPUFREQ_THERMAL_MIN_STEP + 1))
- cpufreq_thermal_reduction_pctg[cpu]--;
+ per_cpu(cpufreq_thermal_reduction_pctg, cpu)--;
else
- cpufreq_thermal_reduction_pctg[cpu] = 0;
+ per_cpu(cpufreq_thermal_reduction_pctg, cpu) = 0;
cpufreq_update_policy(cpu);
/* We reached max freq again and can leave passive mode */
- return !cpufreq_thermal_reduction_pctg[cpu];
+ return !per_cpu(cpufreq_thermal_reduction_pctg, cpu);
}
static int acpi_thermal_cpufreq_notifier(struct notifier_block *nb,
@@ -147,9 +147,10 @@ static int acpi_thermal_cpufreq_notifier(struct notifier_block *nb,
if (event != CPUFREQ_ADJUST)
goto out;
- max_freq =
- (policy->cpuinfo.max_freq *
- (100 - cpufreq_thermal_reduction_pctg[policy->cpu] * 20)) / 100;
+ max_freq = (
+ policy->cpuinfo.max_freq *
+ (100 - per_cpu(cpufreq_thermal_reduction_pctg, policy->cpu) * 20)
+ ) / 100;
cpufreq_verify_within_limits(policy, 0, max_freq);
@@ -174,7 +175,7 @@ static int cpufreq_get_cur_state(unsigned int cpu)
if (!cpu_has_cpufreq(cpu))
return 0;
- return cpufreq_thermal_reduction_pctg[cpu];
+ return per_cpu(cpufreq_thermal_reduction_pctg, cpu);
}
static int cpufreq_set_cur_state(unsigned int cpu, int state)
@@ -182,7 +183,7 @@ static int cpufreq_set_cur_state(unsigned int cpu, int state)
if (!cpu_has_cpufreq(cpu))
return 0;
- cpufreq_thermal_reduction_pctg[cpu] = state;
+ per_cpu(cpufreq_thermal_reduction_pctg, cpu) = state;
cpufreq_update_policy(cpu);
return 0;
}
@@ -191,8 +192,9 @@ void acpi_thermal_cpufreq_init(void)
{
int i;
- for (i = 0; i < NR_CPUS; i++)
- cpufreq_thermal_reduction_pctg[i] = 0;
+ for (i = 0; i < nr_cpu_ids; i++)
+ if (cpu_present(i))
+ per_cpu(cpufreq_thermal_reduction_pctg, i) = 0;
i = cpufreq_register_notifier(&acpi_thermal_cpufreq_notifier_block,
CPUFREQ_POLICY_NOTIFIER);
diff --git a/drivers/atm/nicstar.c b/drivers/atm/nicstar.c
index 38c769f8d2b..3da804b1627 100644
--- a/drivers/atm/nicstar.c
+++ b/drivers/atm/nicstar.c
@@ -415,7 +415,7 @@ static int __devinit ns_init_card(int i, struct pci_dev *pcidev)
card->pcidev = pcidev;
membase = pci_resource_start(pcidev, 1);
card->membase = ioremap(membase, NS_IOREMAP_SIZE);
- if (card->membase == 0)
+ if (!card->membase)
{
printk("nicstar%d: can't ioremap() membase.\n",i);
error = 3;
diff --git a/drivers/char/drm/r128_cce.c b/drivers/char/drm/r128_cce.c
index f36adbd3aaf..c31afbde62e 100644
--- a/drivers/char/drm/r128_cce.c
+++ b/drivers/char/drm/r128_cce.c
@@ -817,7 +817,7 @@ static struct drm_buf *r128_freelist_get(struct drm_device * dev)
for (i = 0; i < dma->buf_count; i++) {
buf = dma->buflist[i];
buf_priv = buf->dev_private;
- if (buf->file_priv == 0)
+ if (!buf->file_priv)
return buf;
}
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 4d3c7018f0c..98b65a23099 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -1180,7 +1180,7 @@ struct tty_driver *tty_find_polling_driver(char *name, int *line)
if (*str == ',')
str++;
if (*str == '\0')
- str = 0;
+ str = NULL;
if (tty_line >= 0 && tty_line <= p->num && p->poll_init &&
!p->poll_init(p, tty_line, str)) {
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 35a26a3e5f6..d3575f5ec6d 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -118,9 +118,11 @@ static void handle_update(struct work_struct *work);
static BLOCKING_NOTIFIER_HEAD(cpufreq_policy_notifier_list);
static struct srcu_notifier_head cpufreq_transition_notifier_list;
+static bool init_cpufreq_transition_notifier_list_called;
static int __init init_cpufreq_transition_notifier_list(void)
{
srcu_init_notifier_head(&cpufreq_transition_notifier_list);
+ init_cpufreq_transition_notifier_list_called = true;
return 0;
}
pure_initcall(init_cpufreq_transition_notifier_list);
@@ -216,7 +218,7 @@ static void cpufreq_debug_disable_ratelimit(void)
}
void cpufreq_debug_printk(unsigned int type, const char *prefix,
- const char *fmt, ...)
+ const char *fmt, ...)
{
char s[256];
va_list args;
@@ -378,7 +380,7 @@ static struct cpufreq_governor *__find_governor(const char *str_governor)
/**
* cpufreq_parse_governor - parse a governor string
*/
-static int cpufreq_parse_governor (char *str_governor, unsigned int *policy,
+static int cpufreq_parse_governor(char *str_governor, unsigned int *policy,
struct cpufreq_governor **governor)
{
int err = -EINVAL;
@@ -446,7 +448,7 @@ extern struct sysdev_class cpu_sysdev_class;
#define show_one(file_name, object) \
static ssize_t show_##file_name \
-(struct cpufreq_policy * policy, char *buf) \
+(struct cpufreq_policy *policy, char *buf) \
{ \
return sprintf (buf, "%u\n", policy->object); \
}
@@ -465,7 +467,7 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data,
*/
#define store_one(file_name, object) \
static ssize_t store_##file_name \
-(struct cpufreq_policy * policy, const char *buf, size_t count) \
+(struct cpufreq_policy *policy, const char *buf, size_t count) \
{ \
unsigned int ret = -EINVAL; \
struct cpufreq_policy new_policy; \
@@ -490,8 +492,8 @@ store_one(scaling_max_freq,max);
/**
* show_cpuinfo_cur_freq - current CPU frequency as detected by hardware
*/
-static ssize_t show_cpuinfo_cur_freq (struct cpufreq_policy * policy,
- char *buf)
+static ssize_t show_cpuinfo_cur_freq(struct cpufreq_policy *policy,
+ char *buf)
{
unsigned int cur_freq = __cpufreq_get(policy->cpu);
if (!cur_freq)
@@ -503,8 +505,7 @@ static ssize_t show_cpuinfo_cur_freq (struct cpufreq_policy * policy,
/**
* show_scaling_governor - show the current policy for the specified CPU
*/
-static ssize_t show_scaling_governor (struct cpufreq_policy * policy,
- char *buf)
+static ssize_t show_scaling_governor(struct cpufreq_policy *policy, char *buf)
{
if(policy->policy == CPUFREQ_POLICY_POWERSAVE)
return sprintf(buf, "powersave\n");
@@ -519,8 +520,8 @@ static ssize_t show_scaling_governor (struct cpufreq_policy * policy,
/**
* store_scaling_governor - store policy for the specified CPU
*/
-static ssize_t store_scaling_governor (struct cpufreq_policy * policy,
- const char *buf, size_t count)
+static ssize_t store_scaling_governor(struct cpufreq_policy *policy,
+ const char *buf, size_t count)
{
unsigned int ret = -EINVAL;
char str_governor[16];
@@ -554,7 +555,7 @@ static ssize_t store_scaling_governor (struct cpufreq_policy * policy,
/**
* show_scaling_driver - show the cpufreq driver currently loaded
*/
-static ssize_t show_scaling_driver (struct cpufreq_policy * policy, char *buf)
+static ssize_t show_scaling_driver(struct cpufreq_policy *policy, char *buf)
{
return scnprintf(buf, CPUFREQ_NAME_LEN, "%s\n", cpufreq_driver->name);
}
@@ -562,8 +563,8 @@ static ssize_t show_scaling_driver (struct cpufreq_policy * policy, char *buf)
/**
* show_scaling_available_governors - show the available CPUfreq governors
*/
-static ssize_t show_scaling_available_governors (struct cpufreq_policy *policy,
- char *buf)
+static ssize_t show_scaling_available_governors(struct cpufreq_policy *policy,
+ char *buf)
{
ssize_t i = 0;
struct cpufreq_governor *t;
@@ -585,7 +586,7 @@ out:
/**
* show_affected_cpus - show the CPUs affected by each transition
*/
-static ssize_t show_affected_cpus (struct cpufreq_policy * policy, char *buf)
+static ssize_t show_affected_cpus(struct cpufreq_policy *policy, char *buf)
{
ssize_t i = 0;
unsigned int cpu;
@@ -602,7 +603,7 @@ static ssize_t show_affected_cpus (struct cpufreq_policy * policy, char *buf)
}
static ssize_t store_scaling_setspeed(struct cpufreq_policy *policy,
- const char *buf, size_t count)
+ const char *buf, size_t count)
{
unsigned int freq = 0;
unsigned int ret;
@@ -651,7 +652,7 @@ define_one_rw(scaling_max_freq);
define_one_rw(scaling_governor);
define_one_rw(scaling_setspeed);
-static struct attribute * default_attrs[] = {
+static struct attribute *default_attrs[] = {
&cpuinfo_min_freq.attr,
&cpuinfo_max_freq.attr,
&scaling_min_freq.attr,
@@ -667,10 +668,10 @@ static struct attribute * default_attrs[] = {
#define to_policy(k) container_of(k,struct cpufreq_policy,kobj)
#define to_attr(a) container_of(a,struct freq_attr,attr)
-static ssize_t show(struct kobject * kobj, struct attribute * attr ,char * buf)
+static ssize_t show(struct kobject *kobj, struct attribute *attr ,char *buf)
{
- struct cpufreq_policy * policy = to_policy(kobj);
- struct freq_attr * fattr = to_attr(attr);
+ struct cpufreq_policy *policy = to_policy(kobj);
+ struct freq_attr *fattr = to_attr(attr);
ssize_t ret = -EINVAL;
policy = cpufreq_cpu_get(policy->cpu);
if (!policy)
@@ -691,11 +692,11 @@ no_policy:
return ret;
}
-static ssize_t store(struct kobject * kobj, struct attribute * attr,
- const char * buf, size_t count)
+static ssize_t store(struct kobject *kobj, struct attribute *attr,
+ const char *buf, size_t count)
{
- struct cpufreq_policy * policy = to_policy(kobj);
- struct freq_attr * fattr = to_attr(attr);
+ struct cpufreq_policy *policy = to_policy(kobj);
+ struct freq_attr *fattr = to_attr(attr);
ssize_t ret = -EINVAL;
policy = cpufreq_cpu_get(policy->cpu);
if (!policy)
@@ -716,9 +717,9 @@ no_policy:
return ret;
}
-static void cpufreq_sysfs_release(struct kobject * kobj)
+static void cpufreq_sysfs_release(struct kobject *kobj)
{
- struct cpufreq_policy * policy = to_policy(kobj);
+ struct cpufreq_policy *policy = to_policy(kobj);
dprintk("last reference is dropped\n");
complete(&policy->kobj_unregister);
}
@@ -740,7 +741,7 @@ static struct kobj_type ktype_cpufreq = {
*
* Adds the cpufreq interface for a CPU device.
*/
-static int cpufreq_add_dev (struct sys_device * sys_dev)
+static int cpufreq_add_dev(struct sys_device *sys_dev)
{
unsigned int cpu = sys_dev->id;
int ret = 0;
@@ -800,7 +801,6 @@ static int cpufreq_add_dev (struct sys_device * sys_dev)
ret = cpufreq_driver->init(policy);
if (ret) {
dprintk("initialization failed\n");
- unlock_policy_rwsem_write(cpu);
goto err_out;
}
policy->user_policy.min = policy->cpuinfo.min_freq;
@@ -823,7 +823,7 @@ static int cpufreq_add_dev (struct sys_device * sys_dev)
/* check for existing affected CPUs. They may not be aware
* of it due to CPU Hotplug.
*/
- managed_policy = cpufreq_cpu_get(j);
+ managed_policy = cpufreq_cpu_get(j); // FIXME: Where is this released? What about error paths?
if (unlikely(managed_policy)) {
/* Set proper policy_cpu */
@@ -842,14 +842,11 @@ static int cpufreq_add_dev (struct sys_device * sys_dev)
ret = sysfs_create_link(&sys_dev->kobj,
&managed_policy->kobj,
"cpufreq");
- if (ret) {
- unlock_policy_rwsem_write(cpu);
+ if (ret)
goto err_out_driver_exit;
- }
cpufreq_debug_enable_ratelimit();
ret = 0;
- unlock_policy_rwsem_write(cpu);
goto err_out_driver_exit; /* call driver->exit() */
}
}
@@ -859,33 +856,26 @@ static int cpufreq_add_dev (struct sys_device * sys_dev)
/* prepare interface data */
ret = kobject_init_and_add(&policy->kobj, &ktype_cpufreq, &sys_dev->kobj,
"cpufreq");
- if (ret) {
- unlock_policy_rwsem_write(cpu);
+ if (ret)
goto err_out_driver_exit;
- }
+
/* set up files for this cpu device */
drv_attr = cpufreq_driver->attr;
while ((drv_attr) && (*drv_attr)) {
ret = sysfs_create_file(&policy->kobj, &((*drv_attr)->attr));
- if (ret) {
- unlock_policy_rwsem_write(cpu);
+ if (ret)
goto err_out_driver_exit;
- }
drv_attr++;
}
- if (cpufreq_driver->get){
+ if (cpufreq_driver->get) {
ret = sysfs_create_file(&policy->kobj, &cpuinfo_cur_freq.attr);
- if (ret) {
- unlock_policy_rwsem_write(cpu);
+ if (ret)
goto err_out_driver_exit;
- }
}
- if (cpufreq_driver->target){
+ if (cpufreq_driver->target) {
ret = sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr);
- if (ret) {
- unlock_policy_rwsem_write(cpu);
+ if (ret)
goto err_out_driver_exit;
- }
}
spin_lock_irqsave(&cpufreq_driver_lock, flags);
@@ -907,10 +897,8 @@ static int cpufreq_add_dev (struct sys_device * sys_dev)
cpu_sys_dev = get_cpu_sysdev(j);
ret = sysfs_create_link(&cpu_sys_dev->kobj, &policy->kobj,
"cpufreq");
- if (ret) {
- unlock_policy_rwsem_write(cpu);
+ if (ret)
goto err_out_unregister;
- }
}
policy->governor = NULL; /* to assure that the starting sequence is
@@ -950,6 +938,7 @@ err_out_driver_exit:
cpufreq_driver->exit(policy);
err_out:
+ unlock_policy_rwsem_write(cpu);
kfree(policy);
nomem_out:
@@ -967,7 +956,7 @@ module_out:
* Caller should already have policy_rwsem in write mode for this CPU.
* This routine frees the rwsem before returning.
*/
-static int __cpufreq_remove_dev (struct sys_device * sys_dev)
+static int __cpufreq_remove_dev(struct sys_device *sys_dev)
{
unsigned int cpu = sys_dev->id;
unsigned long flags;
@@ -1071,7 +1060,7 @@ static int __cpufreq_remove_dev (struct sys_device * sys_dev)
}
-static int cpufreq_remove_dev (struct sys_device * sys_dev)
+static int cpufreq_remove_dev(struct sys_device *sys_dev)
{
unsigned int cpu = sys_dev->id;
int retval;
@@ -1138,7 +1127,7 @@ unsigned int cpufreq_quick_get(unsigned int cpu)
cpufreq_cpu_put(policy);
}
- return (ret_freq);
+ return ret_freq;
}
EXPORT_SYMBOL(cpufreq_quick_get);
@@ -1149,7 +1138,7 @@ static unsigned int __cpufreq_get(unsigned int cpu)
unsigned int ret_freq = 0;
if (!cpufreq_driver->get)
- return (ret_freq);
+ return ret_freq;
ret_freq = cpufreq_driver->get(cpu);
@@ -1163,7 +1152,7 @@ static unsigned int __cpufreq_get(unsigned int cpu)
}
}
- return (ret_freq);
+ return ret_freq;
}
/**
@@ -1190,7 +1179,7 @@ unsigned int cpufreq_get(unsigned int cpu)
out_policy:
cpufreq_cpu_put(policy);
out:
- return (ret_freq);
+ return ret_freq;
}
EXPORT_SYMBOL(cpufreq_get);
@@ -1199,7 +1188,7 @@ EXPORT_SYMBOL(cpufreq_get);
* cpufreq_suspend - let the low level driver prepare for suspend
*/
-static int cpufreq_suspend(struct sys_device * sysdev, pm_message_t pmsg)
+static int cpufreq_suspend(struct sys_device *sysdev, pm_message_t pmsg)
{
int cpu = sysdev->id;
int ret = 0;
@@ -1221,22 +1210,18 @@ static int cpufreq_suspend(struct sys_device * sysdev, pm_message_t pmsg)
return -EINVAL;
/* only handle each CPU group once */
- if (unlikely(cpu_policy->cpu != cpu)) {
- cpufreq_cpu_put(cpu_policy);
- return 0;
- }
+ if (unlikely(cpu_policy->cpu != cpu))
+ goto out;
if (cpufreq_driver->suspend) {
ret = cpufreq_driver->suspend(cpu_policy, pmsg);
if (ret) {
printk(KERN_ERR "cpufreq: suspend failed in ->suspend "
"step on CPU %u\n", cpu_policy->cpu);
- cpufreq_cpu_put(cpu_policy);
- return ret;
+ goto out;
}
}
-
if (cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)
goto out;
@@ -1270,7 +1255,7 @@ static int cpufreq_suspend(struct sys_device * sysdev, pm_message_t pmsg)
out:
cpufreq_cpu_put(cpu_policy);
- return 0;
+ return ret;
}
/**
@@ -1281,7 +1266,7 @@ out:
* 3.) schedule call cpufreq_update_policy() ASAP as interrupts are
* restored.
*/
-static int cpufreq_resume(struct sys_device * sysdev)
+static int cpufreq_resume(struct sys_device *sysdev)
{
int cpu = sysdev->id;
int ret = 0;
@@ -1302,18 +1287,15 @@ static int cpufreq_resume(struct sys_device * sysdev)
return -EINVAL;
/* only handle each CPU group once */
- if (unlikely(cpu_policy->cpu != cpu)) {
- cpufreq_cpu_put(cpu_policy);
- return 0;
- }
+ if (unlikely(cpu_policy->cpu != cpu))
+ goto fail;
if (cpufreq_driver->resume) {
ret = cpufreq_driver->resume(cpu_policy);
if (ret) {
printk(KERN_ERR "cpufreq: resume failed in ->resume "
"step on CPU %u\n", cpu_policy->cpu);
- cpufreq_cpu_put(cpu_policy);
- return ret;
+ goto fail;
}
}
@@ -1353,6 +1335,7 @@ static int cpufreq_resume(struct sys_device * sysdev)
out:
schedule_work(&cpu_policy->update);
+fail:
cpufreq_cpu_put(cpu_policy);
return ret;
}
@@ -1386,6 +1369,8 @@ int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list)
{
int ret;
+ WARN_ON(!init_cpufreq_transition_notifier_list_called);
+
switch (list) {
case CPUFREQ_TRANSITION_NOTIFIER:
ret = srcu_notifier_chain_register(
@@ -1848,7 +1833,7 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data)
cpufreq_debug_enable_ratelimit();
}
- return (ret);
+ return ret;
}
EXPORT_SYMBOL_GPL(cpufreq_register_driver);
diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c
index 070421a5480..ef09e069433 100644
--- a/drivers/cpufreq/cpufreq_stats.c
+++ b/drivers/cpufreq/cpufreq_stats.c
@@ -114,7 +114,7 @@ show_trans_table(struct cpufreq_policy *policy, char *buf)
stat->freq_table[i]);
}
if (len >= PAGE_SIZE)
- return len;
+ return PAGE_SIZE;
len += snprintf(buf + len, PAGE_SIZE - len, "\n");
@@ -131,8 +131,12 @@ show_trans_table(struct cpufreq_policy *policy, char *buf)
len += snprintf(buf + len, PAGE_SIZE - len, "%9u ",
stat->trans_table[i*stat->max_state+j]);
}
+ if (len >= PAGE_SIZE)
+ break;
len += snprintf(buf + len, PAGE_SIZE - len, "\n");
}
+ if (len >= PAGE_SIZE)
+ return PAGE_SIZE;
return len;
}
CPUFREQ_STATDEVICE_ATTR(trans_table,0444,show_trans_table);
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index 29adaa781cb..e2bae8dde35 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -42,7 +42,10 @@ struct page {
* to show when page is mapped
* & limit reverse map searches.
*/
- unsigned int inuse; /* SLUB: Nr of objects */
+ struct { /* SLUB */
+ u16 inuse;
+ u16 objects;
+ };
};
union {
struct {
diff --git a/include/linux/slub_def.h b/include/linux/slub_def.h
index 79d59c937fa..71e43a12ebb 100644
--- a/include/linux/slub_def.h
+++ b/include/linux/slub_def.h
@@ -29,6 +29,7 @@ enum stat_item {
DEACTIVATE_TO_HEAD, /* Cpu slab was moved to the head of partials */
DEACTIVATE_TO_TAIL, /* Cpu slab was moved to the tail of partials */
DEACTIVATE_REMOTE_FREES,/* Slab contained remotely freed objects */
+ ORDER_FALLBACK, /* Number of times fallback was necessary */
NR_SLUB_STAT_ITEMS };
struct kmem_cache_cpu {
@@ -48,11 +49,21 @@ struct kmem_cache_node {
struct list_head partial;
#ifdef CONFIG_SLUB_DEBUG
atomic_long_t nr_slabs;
+ atomic_long_t total_objects;
struct list_head full;
#endif
};
/*
+ * Word size structure that can be atomically updated or read and that
+ * contains both the order and the number of objects that a slab of the
+ * given order would contain.
+ */
+struct kmem_cache_order_objects {
+ unsigned long x;
+};
+
+/*
* Slab cache management.
*/
struct kmem_cache {
@@ -61,7 +72,7 @@ struct kmem_cache {
int size; /* The size of an object including meta data */
int objsize; /* The size of an object without meta data */
int offset; /* Free pointer offset. */
- int order; /* Current preferred allocation order */
+ struct kmem_cache_order_objects oo;
/*
* Avoid an extra cache line for UP, SMP and for the node local to
@@ -70,7 +81,8 @@ struct kmem_cache {
struct kmem_cache_node local_node;
/* Allocation and freeing of slabs */
- int objects; /* Number of objects in slab */
+ struct kmem_cache_order_objects max;
+ struct kmem_cache_order_objects min;
gfp_t allocflags; /* gfp flags to use on each alloc */
int refcount; /* Refcount for slab cache destroy */
void (*ctor)(struct kmem_cache *, void *);
diff --git a/init/do_mounts_md.c b/init/do_mounts_md.c
index 753dc54a664..7473b0c59d4 100644
--- a/init/do_mounts_md.c
+++ b/init/do_mounts_md.c
@@ -133,7 +133,7 @@ static void __init md_setup_drive(void)
else
dev = MKDEV(MD_MAJOR, minor);
create_dev(name, dev);
- for (i = 0; i < MD_SB_DISKS && devname != 0; i++) {
+ for (i = 0; i < MD_SB_DISKS && devname != NULL; i++) {
char *p;
char comp_name[64];
u32 rdev;
diff --git a/init/do_mounts_rd.c b/init/do_mounts_rd.c
index 3ac5904d1b1..46dfd64ae8f 100644
--- a/init/do_mounts_rd.c
+++ b/init/do_mounts_rd.c
@@ -212,7 +212,7 @@ int __init rd_load_image(char *from)
}
buf = kmalloc(BLOCK_SIZE, GFP_KERNEL);
- if (buf == 0) {
+ if (!buf) {
printk(KERN_ERR "RAMDISK: could not allocate buffer\n");
goto done;
}
diff --git a/kernel/cpuset.c b/kernel/cpuset.c
index 024888bb981..48a976c52cf 100644
--- a/kernel/cpuset.c
+++ b/kernel/cpuset.c
@@ -1265,7 +1265,8 @@ static ssize_t cpuset_common_file_write(struct cgroup *cont,
return -E2BIG;
/* +1 for nul-terminator */
- if ((buffer = kmalloc(nbytes + 1, GFP_KERNEL)) == 0)
+ buffer = kmalloc(nbytes + 1, GFP_KERNEL);
+ if (!buffer)
return -ENOMEM;
if (copy_from_user(buffer, userbuf, nbytes)) {
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c
index e379ef0e9c2..dea4c9124ac 100644
--- a/kernel/hrtimer.c
+++ b/kernel/hrtimer.c
@@ -590,7 +590,6 @@ static inline int hrtimer_enqueue_reprogram(struct hrtimer *timer,
list_add_tail(&timer->cb_entry,
&base->cpu_base->cb_pending);
timer->state = HRTIMER_STATE_PENDING;
- raise_softirq(HRTIMER_SOFTIRQ);
return 1;
default:
BUG();
@@ -633,6 +632,11 @@ static int hrtimer_switch_to_hres(void)
return 1;
}
+static inline void hrtimer_raise_softirq(void)
+{
+ raise_softirq(HRTIMER_SOFTIRQ);
+}
+
#else
static inline int hrtimer_hres_active(void) { return 0; }
@@ -651,6 +655,7 @@ static inline int hrtimer_reprogram(struct hrtimer *timer,
{
return 0;
}
+static inline void hrtimer_raise_softirq(void) { }
#endif /* CONFIG_HIGH_RES_TIMERS */
@@ -850,7 +855,7 @@ hrtimer_start(struct hrtimer *timer, ktime_t tim, const enum hrtimer_mode mode)
{
struct hrtimer_clock_base *base, *new_base;
unsigned long flags;
- int ret;
+ int ret, raise;
base = lock_hrtimer_base(timer, &flags);
@@ -884,8 +889,18 @@ hrtimer_start(struct hrtimer *timer, ktime_t tim, const enum hrtimer_mode mode)
enqueue_hrtimer(timer, new_base,
new_base->cpu_base == &__get_cpu_var(hrtimer_bases));
+ /*
+ * The timer may be expired and moved to the cb_pending
+ * list. We can not raise the softirq with base lock held due
+ * to a possible deadlock with runqueue lock.
+ */
+ raise = timer->state == HRTIMER_STATE_PENDING;
+
unlock_hrtimer_base(timer, &flags);
+ if (raise)
+ hrtimer_raise_softirq();
+
return ret;
}
EXPORT_SYMBOL_GPL(hrtimer_start);
diff --git a/kernel/pid_namespace.c b/kernel/pid_namespace.c
index 6d792b66d85..5ca37fa50be 100644
--- a/kernel/pid_namespace.c
+++ b/kernel/pid_namespace.c
@@ -92,7 +92,7 @@ static struct pid_namespace *create_pid_namespace(int level)
atomic_set(&ns->pidmap[0].nr_free, BITS_PER_PAGE - 1);
for (i = 1; i < PIDMAP_ENTRIES; i++) {
- ns->pidmap[i].page = 0;
+ ns->pidmap[i].page = NULL;
atomic_set(&ns->pidmap[i].nr_free, BITS_PER_PAGE);
}
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index 67e392ed549..dac4b4e5729 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -612,7 +612,7 @@ int generic_ptrace_pokedata(struct task_struct *tsk, long addr, long data)
return (copied == sizeof(data)) ? 0 : -EIO;
}
-#ifdef CONFIG_COMPAT
+#if defined CONFIG_COMPAT && defined __ARCH_WANT_COMPAT_SYS_PTRACE
#include <linux/compat.h>
int compat_ptrace_request(struct task_struct *child, compat_long_t request,
@@ -667,7 +667,6 @@ int compat_ptrace_request(struct task_struct *child, compat_long_t request,
return ret;
}
-#ifdef __ARCH_WANT_COMPAT_SYS_PTRACE
asmlinkage long compat_sys_ptrace(compat_long_t request, compat_long_t pid,
compat_long_t addr, compat_long_t data)
{
@@ -710,6 +709,4 @@ asmlinkage long compat_sys_ptrace(compat_long_t request, compat_long_t pid,
unlock_kernel();
return ret;
}
-#endif /* __ARCH_WANT_COMPAT_SYS_PTRACE */
-
-#endif /* CONFIG_COMPAT */
+#endif /* CONFIG_COMPAT && __ARCH_WANT_COMPAT_SYS_PTRACE */
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index df28c1773fb..2c37c67ed8c 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -204,7 +204,7 @@ static struct page *alloc_fresh_huge_page_node(int nid)
if (page) {
if (arch_prepare_hugepage(page)) {
__free_pages(page, HUGETLB_PAGE_ORDER);
- return 0;
+ return NULL;
}
set_compound_page_dtor(page, free_huge_page);
spin_lock(&hugetlb_lock);
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index c4ba85c8cb0..b17dca7249f 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -29,6 +29,8 @@
#include <asm/tlbflush.h>
+#include "internal.h"
+
/* add this memory to iomem resource */
static struct resource *register_memory_resource(u64 start, u64 size)
{
diff --git a/mm/slob.c b/mm/slob.c
index e2c3c0ec546..6038cbadf79 100644
--- a/mm/slob.c
+++ b/mm/slob.c
@@ -533,7 +533,8 @@ struct kmem_cache *kmem_cache_create(const char *name, size_t size,
{
struct kmem_cache *c;
- c = slob_alloc(sizeof(struct kmem_cache), flags, 0, -1);
+ c = slob_alloc(sizeof(struct kmem_cache),
+ flags, ARCH_KMALLOC_MINALIGN, -1);
if (c) {
c->name = name;
diff --git a/mm/slub.c b/mm/slub.c
index 38914bc64ac..992ecd4f0d3 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -149,25 +149,6 @@ static inline void ClearSlabDebug(struct page *page)
/* Enable to test recovery from slab corruption on boot */
#undef SLUB_RESILIENCY_TEST
-#if PAGE_SHIFT <= 12
-
-/*
- * Small page size. Make sure that we do not fragment memory
- */
-#define DEFAULT_MAX_ORDER 1
-#define DEFAULT_MIN_OBJECTS 4
-
-#else
-
-/*
- * Large page machines are customarily able to handle larger
- * page orders.
- */
-#define DEFAULT_MAX_ORDER 2
-#define DEFAULT_MIN_OBJECTS 8
-
-#endif
-
/*
* Mininum number of partial slabs. These will be left on the partial
* lists even if they are empty. kmem_cache_shrink may reclaim them.
@@ -204,8 +185,6 @@ static inline void ClearSlabDebug(struct page *page)
/* Internal SLUB flags */
#define __OBJECT_POISON 0x80000000 /* Poison object */
#define __SYSFS_ADD_DEFERRED 0x40000000 /* Not yet visible via sysfs */
-#define __KMALLOC_CACHE 0x20000000 /* objects freed using kfree */
-#define __PAGE_ALLOC_FALLBACK 0x10000000 /* Allow fallback to page alloc */
static int kmem_size = sizeof(struct kmem_cache);
@@ -296,7 +275,7 @@ static inline int check_valid_pointer(struct kmem_cache *s,
return 1;
base = page_address(page);
- if (object < base || object >= base + s->objects * s->size ||
+ if (object < base || object >= base + page->objects * s->size ||
(object - base) % s->size) {
return 0;
}
@@ -322,8 +301,8 @@ static inline void set_freepointer(struct kmem_cache *s, void *object, void *fp)
}
/* Loop over all objects in a slab */
-#define for_each_object(__p, __s, __addr) \
- for (__p = (__addr); __p < (__addr) + (__s)->objects * (__s)->size;\
+#define for_each_object(__p, __s, __addr, __objects) \
+ for (__p = (__addr); __p < (__addr) + (__objects) * (__s)->size;\
__p += (__s)->size)
/* Scan freelist */
@@ -336,6 +315,26 @@ static inline int slab_index(void *p, struct kmem_cache *s, void *addr)
return (p - addr) / s->size;
}
+static inline struct kmem_cache_order_objects oo_make(int order,
+ unsigned long size)
+{
+ struct kmem_cache_order_objects x = {
+ (order << 16) + (PAGE_SIZE << order) / size
+ };
+
+ return x;
+}
+
+static inline int oo_order(struct kmem_cache_order_objects x)
+{
+ return x.x >> 16;
+}
+
+static inline int oo_objects(struct kmem_cache_order_objects x)
+{
+ return x.x & ((1 << 16) - 1);
+}
+
#ifdef CONFIG_SLUB_DEBUG
/*
* Debug settings:
@@ -446,8 +445,8 @@ static void print_tracking(struct kmem_cache *s, void *object)
static void print_page_info(struct page *page)
{
- printk(KERN_ERR "INFO: Slab 0x%p used=%u fp=0x%p flags=0x%04lx\n",
- page, page->inuse, page->freelist, page->flags);
+ printk(KERN_ERR "INFO: Slab 0x%p objects=%u used=%u fp=0x%p flags=0x%04lx\n",
+ page, page->objects, page->inuse, page->freelist, page->flags);
}
@@ -647,6 +646,7 @@ static int check_pad_bytes(struct kmem_cache *s, struct page *page, u8 *p)
p + off, POISON_INUSE, s->size - off);
}
+/* Check the pad bytes at the end of a slab page */
static int slab_pad_check(struct kmem_cache *s, struct page *page)
{
u8 *start;
@@ -659,20 +659,20 @@ static int slab_pad_check(struct kmem_cache *s, struct page *page)
return 1;
start = page_address(page);
- end = start + (PAGE_SIZE << s->order);
- length = s->objects * s->size;
- remainder = end - (start + length);
+ length = (PAGE_SIZE << compound_order(page));
+ end = start + length;
+ remainder = length % s->size;
if (!remainder)
return 1;
- fault = check_bytes(start + length, POISON_INUSE, remainder);
+ fault = check_bytes(end - remainder, POISON_INUSE, remainder);
if (!fault)
return 1;
while (end > fault && end[-1] == POISON_INUSE)
end--;
slab_err(s, page, "Padding overwritten. 0x%p-0x%p", fault, end - 1);
- print_section("Padding", start, length);
+ print_section("Padding", end - remainder, remainder);
restore_bytes(s, "slab padding", POISON_INUSE, start, end);
return 0;
@@ -734,15 +734,24 @@ static int check_object(struct kmem_cache *s, struct page *page,
static int check_slab(struct kmem_cache *s, struct page *page)
{
+ int maxobj;
+
VM_BUG_ON(!irqs_disabled());
if (!PageSlab(page)) {
slab_err(s, page, "Not a valid slab page");
return 0;
}
- if (page->inuse > s->objects) {
+
+ maxobj = (PAGE_SIZE << compound_order(page)) / s->size;
+ if (page->objects > maxobj) {
+ slab_err(s, page, "objects %u > max %u",
+ s->name, page->objects, maxobj);
+ return 0;
+ }
+ if (page->inuse > page->objects) {
slab_err(s, page, "inuse %u > max %u",
- s->name, page->inuse, s->objects);
+ s->name, page->inuse, page->objects);
return 0;
}
/* Slab_pad_check fixes things up after itself */
@@ -759,8 +768,9 @@ static int on_freelist(struct kmem_cache *s, struct page *page, void *search)
int nr = 0;
void *fp = page->freelist;
void *object = NULL;
+ unsigned long max_objects;
- while (fp && nr <= s->objects) {
+ while (fp && nr <= page->objects) {
if (fp == search)
return 1;
if (!check_valid_pointer(s, page, fp)) {
@@ -772,7 +782,7 @@ static int on_freelist(struct kmem_cache *s, struct page *page, void *search)
} else {
slab_err(s, page, "Freepointer corrupt");
page->freelist = NULL;
- page->inuse = s->objects;
+ page->inuse = page->objects;
slab_fix(s, "Freelist cleared");
return 0;
}
@@ -783,10 +793,20 @@ static int on_freelist(struct kmem_cache *s, struct page *page, void *search)
nr++;
}
- if (page->inuse != s->objects - nr) {
+ max_objects = (PAGE_SIZE << compound_order(page)) / s->size;
+ if (max_objects > 65535)
+ max_objects = 65535;
+
+ if (page->objects != max_objects) {
+ slab_err(s, page, "Wrong number of objects. Found %d but "
+ "should be %d", page->objects, max_objects);
+ page->objects = max_objects;
+ slab_fix(s, "Number of objects adjusted.");
+ }
+ if (page->inuse != page->objects - nr) {
slab_err(s, page, "Wrong object count. Counter is %d but "
- "counted were %d", page->inuse, s->objects - nr);
- page->inuse = s->objects - nr;
+ "counted were %d", page->inuse, page->objects - nr);
+ page->inuse = page->objects - nr;
slab_fix(s, "Object count adjusted.");
}
return search == NULL;
@@ -840,7 +860,7 @@ static inline unsigned long slabs_node(struct kmem_cache *s, int node)
return atomic_long_read(&n->nr_slabs);
}
-static inline void inc_slabs_node(struct kmem_cache *s, int node)
+static inline void inc_slabs_node(struct kmem_cache *s, int node, int objects)
{
struct kmem_cache_node *n = get_node(s, node);
@@ -850,14 +870,17 @@ static inline void inc_slabs_node(struct kmem_cache *s, int node)
* dilemma by deferring the increment of the count during
* bootstrap (see early_kmem_cache_node_alloc).
*/
- if (!NUMA_BUILD || n)
+ if (!NUMA_BUILD || n) {
atomic_long_inc(&n->nr_slabs);
+ atomic_long_add(objects, &n->total_objects);
+ }
}
-static inline void dec_slabs_node(struct kmem_cache *s, int node)
+static inline void dec_slabs_node(struct kmem_cache *s, int node, int objects)
{
struct kmem_cache_node *n = get_node(s, node);
atomic_long_dec(&n->nr_slabs);
+ atomic_long_sub(objects, &n->total_objects);
}
/* Object debug checks for alloc/free paths */
@@ -905,7 +928,7 @@ bad:
* as used avoids touching the remaining objects.
*/
slab_fix(s, "Marking all objects used");
- page->inuse = s->objects;
+ page->inuse = page->objects;
page->freelist = NULL;
}
return 0;
@@ -1055,31 +1078,52 @@ static inline unsigned long kmem_cache_flags(unsigned long objsize,
static inline unsigned long slabs_node(struct kmem_cache *s, int node)
{ return 0; }
-static inline void inc_slabs_node(struct kmem_cache *s, int node) {}
-static inline void dec_slabs_node(struct kmem_cache *s, int node) {}
+static inline void inc_slabs_node(struct kmem_cache *s, int node,
+ int objects) {}
+static inline void dec_slabs_node(struct kmem_cache *s, int node,
+ int objects) {}
#endif
+
/*
* Slab allocation and freeing
*/
+static inline struct page *alloc_slab_page(gfp_t flags, int node,
+ struct kmem_cache_order_objects oo)
+{
+ int order = oo_order(oo);
+
+ if (node == -1)
+ return alloc_pages(flags, order);
+ else
+ return alloc_pages_node(node, flags, order);
+}
+
static struct page *allocate_slab(struct kmem_cache *s, gfp_t flags, int node)
{
struct page *page;
- int pages = 1 << s->order;
+ struct kmem_cache_order_objects oo = s->oo;
flags |= s->allocflags;
- if (node == -1)
- page = alloc_pages(flags, s->order);
- else
- page = alloc_pages_node(node, flags, s->order);
-
- if (!page)
- return NULL;
+ page = alloc_slab_page(flags | __GFP_NOWARN | __GFP_NORETRY, node,
+ oo);
+ if (unlikely(!page)) {
+ oo = s->min;
+ /*
+ * Allocation may have failed due to fragmentation.
+ * Try a lower order alloc if possible
+ */
+ page = alloc_slab_page(flags, node, oo);
+ if (!page)
+ return NULL;
+ stat(get_cpu_slab(s, raw_smp_processor_id()), ORDER_FALLBACK);
+ }
+ page->objects = oo_objects(oo);
mod_zone_page_state(page_zone(page),
(s->flags & SLAB_RECLAIM_ACCOUNT) ?
NR_SLAB_RECLAIMABLE : NR_SLAB_UNRECLAIMABLE,
- pages);
+ 1 << oo_order(oo));
return page;
}
@@ -1106,7 +1150,7 @@ static struct page *new_slab(struct kmem_cache *s, gfp_t flags, int node)
if (!page)
goto out;
- inc_slabs_node(s, page_to_nid(page));
+ inc_slabs_node(s, page_to_nid(page), page->objects);
page->slab = s;
page->flags |= 1 << PG_slab;
if (s->flags & (SLAB_DEBUG_FREE | SLAB_RED_ZONE | SLAB_POISON |
@@ -1116,10 +1160,10 @@ static struct page *new_slab(struct kmem_cache *s, gfp_t flags, int node)
start = page_address(page);
if (unlikely(s->flags & SLAB_POISON))
- memset(start, POISON_INUSE, PAGE_SIZE << s->order);
+ memset(start, POISON_INUSE, PAGE_SIZE << compound_order(page));
last = start;
- for_each_object(p, s, start) {
+ for_each_object(p, s, start, page->objects) {
setup_object(s, page, last);
set_freepointer(s, last, p);
last = p;
@@ -1135,13 +1179,15 @@ out:
static void __free_slab(struct kmem_cache *s, struct page *page)
{
- int pages = 1 << s->order;
+ int order = compound_order(page);
+ int pages = 1 << order;
if (unlikely(SlabDebug(page))) {
void *p;
slab_pad_check(s, page);
- for_each_object(p, s, page_address(page))
+ for_each_object(p, s, page_address(page),
+ page->objects)
check_object(s, page, p, 0);
ClearSlabDebug(page);
}
@@ -1153,7 +1199,7 @@ static void __free_slab(struct kmem_cache *s, struct page *page)
__ClearPageSlab(page);
reset_page_mapcount(page);
- __free_pages(page, s->order);
+ __free_pages(page, order);
}
static void rcu_free_slab(struct rcu_head *h)
@@ -1179,7 +1225,7 @@ static void free_slab(struct kmem_cache *s, struct page *page)
static void discard_slab(struct kmem_cache *s, struct page *page)
{
- dec_slabs_node(s, page_to_nid(page));
+ dec_slabs_node(s, page_to_nid(page), page->objects);
free_slab(s, page);
}
@@ -1515,7 +1561,7 @@ load_freelist:
goto debug;
c->freelist = object[c->offset];
- c->page->inuse = s->objects;
+ c->page->inuse = c->page->objects;
c->page->freelist = NULL;
c->node = page_to_nid(c->page);
unlock_out:
@@ -1552,27 +1598,6 @@ new_slab:
c->page = new;
goto load_freelist;
}
-
- /*
- * No memory available.
- *
- * If the slab uses higher order allocs but the object is
- * smaller than a page size then we can fallback in emergencies
- * to the page allocator via kmalloc_large. The page allocator may
- * have failed to obtain a higher order page and we can try to
- * allocate a single page if the object fits into a single page.
- * That is only possible if certain conditions are met that are being
- * checked when a slab is created.
- */
- if (!(gfpflags & __GFP_NORETRY) &&
- (s->flags & __PAGE_ALLOC_FALLBACK)) {
- if (gfpflags & __GFP_WAIT)
- local_irq_enable();
- object = kmalloc_large(s->objsize, gfpflags);
- if (gfpflags & __GFP_WAIT)
- local_irq_disable();
- return object;
- }
return NULL;
debug:
if (!alloc_debug_processing(s, c->page, object, addr))
@@ -1773,8 +1798,8 @@ static struct page *get_object_page(const void *x)
* take the list_lock.
*/
static int slub_min_order;
-static int slub_max_order = DEFAULT_MAX_ORDER;
-static int slub_min_objects = DEFAULT_MIN_OBJECTS;
+static int slub_max_order = PAGE_ALLOC_COSTLY_ORDER;
+static int slub_min_objects;
/*
* Merge control. If this is set then no merging of slab caches will occur.
@@ -1789,7 +1814,7 @@ static int slub_nomerge;
* system components. Generally order 0 allocations should be preferred since
* order 0 does not cause fragmentation in the page allocator. Larger objects
* be problematic to put into order 0 slabs because there may be too much
- * unused space left. We go to a higher order if more than 1/8th of the slab
+ * unused space left. We go to a higher order if more than 1/16th of the slab
* would be wasted.
*
* In order to reach satisfactory performance we must ensure that a minimum
@@ -1814,6 +1839,9 @@ static inline int slab_order(int size, int min_objects,
int rem;
int min_order = slub_min_order;
+ if ((PAGE_SIZE << min_order) / size > 65535)
+ return get_order(size * 65535) - 1;
+
for (order = max(min_order,
fls(min_objects * size - 1) - PAGE_SHIFT);
order <= max_order; order++) {
@@ -1848,8 +1876,10 @@ static inline int calculate_order(int size)
* we reduce the minimum objects required in a slab.
*/
min_objects = slub_min_objects;
+ if (!min_objects)
+ min_objects = 4 * (fls(nr_cpu_ids) + 1);
while (min_objects > 1) {
- fraction = 8;
+ fraction = 16;
while (fraction >= 4) {
order = slab_order(size, min_objects,
slub_max_order, fraction);
@@ -2091,7 +2121,7 @@ static struct kmem_cache_node *early_kmem_cache_node_alloc(gfp_t gfpflags,
init_tracking(kmalloc_caches, n);
#endif
init_kmem_cache_node(n);
- inc_slabs_node(kmalloc_caches, node);
+ inc_slabs_node(kmalloc_caches, node, page->objects);
/*
* lockdep requires consistent irq usage for each lock
@@ -2167,11 +2197,12 @@ static int init_kmem_cache_nodes(struct kmem_cache *s, gfp_t gfpflags)
* calculate_sizes() determines the order and the distribution of data within
* a slab object.
*/
-static int calculate_sizes(struct kmem_cache *s)
+static int calculate_sizes(struct kmem_cache *s, int forced_order)
{
unsigned long flags = s->flags;
unsigned long size = s->objsize;
unsigned long align = s->align;
+ int order;
/*
* Round up object size to the next word boundary. We can only
@@ -2255,26 +2286,16 @@ static int calculate_sizes(struct kmem_cache *s)
*/
size = ALIGN(size, align);
s->size = size;
+ if (forced_order >= 0)
+ order = forced_order;
+ else
+ order = calculate_order(size);
- if ((flags & __KMALLOC_CACHE) &&
- PAGE_SIZE / size < slub_min_objects) {
- /*
- * Kmalloc cache that would not have enough objects in
- * an order 0 page. Kmalloc slabs can fallback to
- * page allocator order 0 allocs so take a reasonably large
- * order that will allows us a good number of objects.
- */
- s->order = max(slub_max_order, PAGE_ALLOC_COSTLY_ORDER);
- s->flags |= __PAGE_ALLOC_FALLBACK;
- s->allocflags |= __GFP_NOWARN;
- } else
- s->order = calculate_order(size);
-
- if (s->order < 0)
+ if (order < 0)
return 0;
s->allocflags = 0;
- if (s->order)
+ if (order)
s->allocflags |= __GFP_COMP;
if (s->flags & SLAB_CACHE_DMA)
@@ -2286,9 +2307,12 @@ static int calculate_sizes(struct kmem_cache *s)
/*
* Determine the number of objects per slab
*/
- s->objects = (PAGE_SIZE << s->order) / size;
+ s->oo = oo_make(order, size);
+ s->min = oo_make(get_order(size), size);
+ if (oo_objects(s->oo) > oo_objects(s->max))
+ s->max = s->oo;
- return !!s->objects;
+ return !!oo_objects(s->oo);
}
@@ -2304,7 +2328,7 @@ static int kmem_cache_open(struct kmem_cache *s, gfp_t gfpflags,
s->align = align;
s->flags = kmem_cache_flags(size, flags, name, ctor);
- if (!calculate_sizes(s))
+ if (!calculate_sizes(s, -1))
goto error;
s->refcount = 1;
@@ -2321,7 +2345,7 @@ error:
if (flags & SLAB_PANIC)
panic("Cannot create slab %s size=%lu realsize=%u "
"order=%u offset=%u flags=%lx\n",
- s->name, (unsigned long)size, s->size, s->order,
+ s->name, (unsigned long)size, s->size, oo_order(s->oo),
s->offset, flags);
return 0;
}
@@ -2367,26 +2391,52 @@ const char *kmem_cache_name(struct kmem_cache *s)
}
EXPORT_SYMBOL(kmem_cache_name);
+static void list_slab_objects(struct kmem_cache *s, struct page *page,
+ const char *text)
+{
+#ifdef CONFIG_SLUB_DEBUG
+ void *addr = page_address(page);
+ void *p;
+ DECLARE_BITMAP(map, page->objects);
+
+ bitmap_zero(map, page->objects);
+ slab_err(s, page, "%s", text);
+ slab_lock(page);
+ for_each_free_object(p, s, page->freelist)
+ set_bit(slab_index(p, s, addr), map);
+
+ for_each_object(p, s, addr, page->objects) {
+
+ if (!test_bit(slab_index(p, s, addr), map)) {
+ printk(KERN_ERR "INFO: Object 0x%p @offset=%tu\n",
+ p, p - addr);
+ print_tracking(s, p);
+ }
+ }
+ slab_unlock(page);
+#endif
+}
+
/*
- * Attempt to free all slabs on a node. Return the number of slabs we
- * were unable to free.
+ * Attempt to free all partial slabs on a node.
*/
-static int free_list(struct kmem_cache *s, struct kmem_cache_node *n,
- struct list_head *list)
+static void free_partial(struct kmem_cache *s, struct kmem_cache_node *n)
{
- int slabs_inuse = 0;
unsigned long flags;
struct page *page, *h;
spin_lock_irqsave(&n->list_lock, flags);
- list_for_each_entry_safe(page, h, list, lru)
+ list_for_each_entry_safe(page, h, &n->partial, lru) {
if (!page->inuse) {
list_del(&page->lru);
discard_slab(s, page);
- } else
- slabs_inuse++;
+ n->nr_partial--;
+ } else {
+ list_slab_objects(s, page,
+ "Objects remaining on kmem_cache_close()");
+ }
+ }
spin_unlock_irqrestore(&n->list_lock, flags);
- return slabs_inuse;
}
/*
@@ -2403,8 +2453,8 @@ static inline int kmem_cache_close(struct kmem_cache *s)
for_each_node_state(node, N_NORMAL_MEMORY) {
struct kmem_cache_node *n = get_node(s, node);
- n->nr_partial -= free_list(s, n, &n->partial);
- if (slabs_node(s, node))
+ free_partial(s, n);
+ if (n->nr_partial || slabs_node(s, node))
return 1;
}
free_kmem_cache_nodes(s);
@@ -2422,8 +2472,11 @@ void kmem_cache_destroy(struct kmem_cache *s)
if (!s->refcount) {
list_del(&s->list);
up_write(&slub_lock);
- if (kmem_cache_close(s))
- WARN_ON(1);
+ if (kmem_cache_close(s)) {
+ printk(KERN_ERR "SLUB %s: %s called for cache that "
+ "still has objects.\n", s->name, __func__);
+ dump_stack();
+ }
sysfs_slab_remove(s);
} else
up_write(&slub_lock);
@@ -2482,7 +2535,7 @@ static struct kmem_cache *create_kmalloc_cache(struct kmem_cache *s,
down_write(&slub_lock);
if (!kmem_cache_open(s, gfp_flags, name, size, ARCH_KMALLOC_MINALIGN,
- flags | __KMALLOC_CACHE, NULL))
+ flags, NULL))
goto panic;
list_add(&s->list, &slab_caches);
@@ -2730,8 +2783,9 @@ int kmem_cache_shrink(struct kmem_cache *s)
struct kmem_cache_node *n;
struct page *page;
struct page *t;
+ int objects = oo_objects(s->max);
struct list_head *slabs_by_inuse =
- kmalloc(sizeof(struct list_head) * s->objects, GFP_KERNEL);
+ kmalloc(sizeof(struct list_head) * objects, GFP_KERNEL);
unsigned long flags;
if (!slabs_by_inuse)
@@ -2744,7 +2798,7 @@ int kmem_cache_shrink(struct kmem_cache *s)
if (!n->nr_partial)
continue;
- for (i = 0; i < s->objects; i++)
+ for (i = 0; i < objects; i++)
INIT_LIST_HEAD(slabs_by_inuse + i);
spin_lock_irqsave(&n->list_lock, flags);
@@ -2776,7 +2830,7 @@ int kmem_cache_shrink(struct kmem_cache *s)
* Rebuild the partial list with the slabs filled up most
* first and the least used slabs at the end.
*/
- for (i = s->objects - 1; i >= 0; i--)
+ for (i = objects - 1; i >= 0; i--)
list_splice(slabs_by_inuse + i, n->partial.prev);
spin_unlock_irqrestore(&n->list_lock, flags);
@@ -2997,9 +3051,6 @@ static int slab_unmergeable(struct kmem_cache *s)
if (slub_nomerge || (s->flags & SLUB_NEVER_MERGE))
return 1;
- if ((s->flags & __PAGE_ALLOC_FALLBACK))
- return 1;
-
if (s->ctor)
return 1;
@@ -3192,7 +3243,8 @@ void *__kmalloc_node_track_caller(size_t size, gfp_t gfpflags,
}
#if (defined(CONFIG_SYSFS) && defined(CONFIG_SLUB_DEBUG)) || defined(CONFIG_SLABINFO)
-static unsigned long count_partial(struct kmem_cache_node *n)
+static unsigned long count_partial(struct kmem_cache_node *n,
+ int (*get_count)(struct page *))
{
unsigned long flags;
unsigned long x = 0;
@@ -3200,10 +3252,25 @@ static unsigned long count_partial(struct kmem_cache_node *n)
spin_lock_irqsave(&n->list_lock, flags);
list_for_each_entry(page, &n->partial, lru)
- x += page->inuse;
+ x += get_count(page);
spin_unlock_irqrestore(&n->list_lock, flags);
return x;
}
+
+static int count_inuse(struct page *page)
+{
+ return page->inuse;
+}
+
+static int count_total(struct page *page)
+{
+ return page->objects;
+}
+
+static int count_free(struct page *page)
+{
+ return page->objects - page->inuse;
+}
#endif
#if defined(CONFIG_SYSFS) && defined(CONFIG_SLUB_DEBUG)
@@ -3218,7 +3285,7 @@ static int validate_slab(struct kmem_cache *s, struct page *page,
return 0;
/* Now we know that a valid freelist exists */
- bitmap_zero(map, s->objects);
+ bitmap_zero(map, page->objects);
for_each_free_object(p, s, page->freelist) {
set_bit(slab_index(p, s, addr), map);
@@ -3226,7 +3293,7 @@ static int validate_slab(struct kmem_cache *s, struct page *page,
return 0;
}
- for_each_object(p, s, addr)
+ for_each_object(p, s, addr, page->objects)
if (!test_bit(slab_index(p, s, addr), map))
if (!check_object(s, page, p, 1))
return 0;
@@ -3292,7 +3359,7 @@ static long validate_slab_cache(struct kmem_cache *s)
{
int node;
unsigned long count = 0;
- unsigned long *map = kmalloc(BITS_TO_LONGS(s->objects) *
+ unsigned long *map = kmalloc(BITS_TO_LONGS(oo_objects(s->max)) *
sizeof(unsigned long), GFP_KERNEL);
if (!map)
@@ -3495,14 +3562,14 @@ static void process_slab(struct loc_track *t, struct kmem_cache *s,
struct page *page, enum track_item alloc)
{
void *addr = page_address(page);
- DECLARE_BITMAP(map, s->objects);
+ DECLARE_BITMAP(map, page->objects);
void *p;
- bitmap_zero(map, s->objects);
+ bitmap_zero(map, page->objects);
for_each_free_object(p, s, page->freelist)
set_bit(slab_index(p, s, addr), map);
- for_each_object(p, s, addr)
+ for_each_object(p, s, addr, page->objects)
if (!test_bit(slab_index(p, s, addr), map))
add_location(t, s, get_track(s, p, alloc));
}
@@ -3592,22 +3659,23 @@ static int list_locations(struct kmem_cache *s, char *buf,
}
enum slab_stat_type {
- SL_FULL,
- SL_PARTIAL,
- SL_CPU,
- SL_OBJECTS
+ SL_ALL, /* All slabs */
+ SL_PARTIAL, /* Only partially allocated slabs */
+ SL_CPU, /* Only slabs used for cpu caches */
+ SL_OBJECTS, /* Determine allocated objects not slabs */
+ SL_TOTAL /* Determine object capacity not slabs */
};
-#define SO_FULL (1 << SL_FULL)
+#define SO_ALL (1 << SL_ALL)
#define SO_PARTIAL (1 << SL_PARTIAL)
#define SO_CPU (1 << SL_CPU)
#define SO_OBJECTS (1 << SL_OBJECTS)
+#define SO_TOTAL (1 << SL_TOTAL)
static ssize_t show_slab_objects(struct kmem_cache *s,
char *buf, unsigned long flags)
{
unsigned long total = 0;
- int cpu;
int node;
int x;
unsigned long *nodes;
@@ -3618,56 +3686,60 @@ static ssize_t show_slab_objects(struct kmem_cache *s,
return -ENOMEM;
per_cpu = nodes + nr_node_ids;
- for_each_possible_cpu(cpu) {
- struct page *page;
- struct kmem_cache_cpu *c = get_cpu_slab(s, cpu);
+ if (flags & SO_CPU) {
+ int cpu;
- if (!c)
- continue;
+ for_each_possible_cpu(cpu) {
+ struct kmem_cache_cpu *c = get_cpu_slab(s, cpu);
- page = c->page;
- node = c->node;
- if (node < 0)
- continue;
- if (page) {
- if (flags & SO_CPU) {
- if (flags & SO_OBJECTS)
- x = page->inuse;
+ if (!c || c->node < 0)
+ continue;
+
+ if (c->page) {
+ if (flags & SO_TOTAL)
+ x = c->page->objects;
+ else if (flags & SO_OBJECTS)
+ x = c->page->inuse;
else
x = 1;
+
total += x;
- nodes[node] += x;
+ nodes[c->node] += x;
}
- per_cpu[node]++;
+ per_cpu[c->node]++;
}
}
- for_each_node_state(node, N_NORMAL_MEMORY) {
- struct kmem_cache_node *n = get_node(s, node);
+ if (flags & SO_ALL) {
+ for_each_node_state(node, N_NORMAL_MEMORY) {
+ struct kmem_cache_node *n = get_node(s, node);
+
+ if (flags & SO_TOTAL)
+ x = atomic_long_read(&n->total_objects);
+ else if (flags & SO_OBJECTS)
+ x = atomic_long_read(&n->total_objects) -
+ count_partial(n, count_free);
- if (flags & SO_PARTIAL) {
- if (flags & SO_OBJECTS)
- x = count_partial(n);
else
- x = n->nr_partial;
+ x = atomic_long_read(&n->nr_slabs);
total += x;
nodes[node] += x;
}
- if (flags & SO_FULL) {
- int full_slabs = atomic_long_read(&n->nr_slabs)
- - per_cpu[node]
- - n->nr_partial;
+ } else if (flags & SO_PARTIAL) {
+ for_each_node_state(node, N_NORMAL_MEMORY) {
+ struct kmem_cache_node *n = get_node(s, node);
- if (flags & SO_OBJECTS)
- x = full_slabs * s->objects;
+ if (flags & SO_TOTAL)
+ x = count_partial(n, count_total);
+ else if (flags & SO_OBJECTS)
+ x = count_partial(n, count_inuse);
else
- x = full_slabs;
+ x = n->nr_partial;
total += x;
nodes[node] += x;
}
}
-
x = sprintf(buf, "%lu", total);
#ifdef CONFIG_NUMA
for_each_node_state(node, N_NORMAL_MEMORY)
@@ -3682,14 +3754,6 @@ static ssize_t show_slab_objects(struct kmem_cache *s,
static int any_slab_objects(struct kmem_cache *s)
{
int node;
- int cpu;
-
- for_each_possible_cpu(cpu) {
- struct kmem_cache_cpu *c = get_cpu_slab(s, cpu);
-
- if (c && c->page)
- return 1;
- }
for_each_online_node(node) {
struct kmem_cache_node *n = get_node(s, node);
@@ -3697,7 +3761,7 @@ static int any_slab_objects(struct kmem_cache *s)
if (!n)
continue;
- if (n->nr_partial || atomic_long_read(&n->nr_slabs))
+ if (atomic_read(&n->total_objects))
return 1;
}
return 0;
@@ -3739,15 +3803,27 @@ SLAB_ATTR_RO(object_size);
static ssize_t objs_per_slab_show(struct kmem_cache *s, char *buf)
{
- return sprintf(buf, "%d\n", s->objects);
+ return sprintf(buf, "%d\n", oo_objects(s->oo));
}
SLAB_ATTR_RO(objs_per_slab);
+static ssize_t order_store(struct kmem_cache *s,
+ const char *buf, size_t length)
+{
+ int order = simple_strtoul(buf, NULL, 10);
+
+ if (order > slub_max_order || order < slub_min_order)
+ return -EINVAL;
+
+ calculate_sizes(s, order);
+ return length;
+}
+
static ssize_t order_show(struct kmem_cache *s, char *buf)
{
- return sprintf(buf, "%d\n", s->order);
+ return sprintf(buf, "%d\n", oo_order(s->oo));
}
-SLAB_ATTR_RO(order);
+SLAB_ATTR(order);
static ssize_t ctor_show(struct kmem_cache *s, char *buf)
{
@@ -3768,7 +3844,7 @@ SLAB_ATTR_RO(aliases);
static ssize_t slabs_show(struct kmem_cache *s, char *buf)
{
- return show_slab_objects(s, buf, SO_FULL|SO_PARTIAL|SO_CPU);
+ return show_slab_objects(s, buf, SO_ALL);
}
SLAB_ATTR_RO(slabs);
@@ -3786,10 +3862,22 @@ SLAB_ATTR_RO(cpu_slabs);
static ssize_t objects_show(struct kmem_cache *s, char *buf)
{
- return show_slab_objects(s, buf, SO_FULL|SO_PARTIAL|SO_CPU|SO_OBJECTS);
+ return show_slab_objects(s, buf, SO_ALL|SO_OBJECTS);
}
SLAB_ATTR_RO(objects);
+static ssize_t objects_partial_show(struct kmem_cache *s, char *buf)
+{
+ return show_slab_objects(s, buf, SO_PARTIAL|SO_OBJECTS);
+}
+SLAB_ATTR_RO(objects_partial);
+
+static ssize_t total_objects_show(struct kmem_cache *s, char *buf)
+{
+ return show_slab_objects(s, buf, SO_ALL|SO_TOTAL);
+}
+SLAB_ATTR_RO(total_objects);
+
static ssize_t sanity_checks_show(struct kmem_cache *s, char *buf)
{
return sprintf(buf, "%d\n", !!(s->flags & SLAB_DEBUG_FREE));
@@ -3869,7 +3957,7 @@ static ssize_t red_zone_store(struct kmem_cache *s,
s->flags &= ~SLAB_RED_ZONE;
if (buf[0] == '1')
s->flags |= SLAB_RED_ZONE;
- calculate_sizes(s);
+ calculate_sizes(s, -1);
return length;
}
SLAB_ATTR(red_zone);
@@ -3888,7 +3976,7 @@ static ssize_t poison_store(struct kmem_cache *s,
s->flags &= ~SLAB_POISON;
if (buf[0] == '1')
s->flags |= SLAB_POISON;
- calculate_sizes(s);
+ calculate_sizes(s, -1);
return length;
}
SLAB_ATTR(poison);
@@ -3907,7 +3995,7 @@ static ssize_t store_user_store(struct kmem_cache *s,
s->flags &= ~SLAB_STORE_USER;
if (buf[0] == '1')
s->flags |= SLAB_STORE_USER;
- calculate_sizes(s);
+ calculate_sizes(s, -1);
return length;
}
SLAB_ATTR(store_user);
@@ -4038,7 +4126,7 @@ STAT_ATTR(DEACTIVATE_EMPTY, deactivate_empty);
STAT_ATTR(DEACTIVATE_TO_HEAD, deactivate_to_head);
STAT_ATTR(DEACTIVATE_TO_TAIL, deactivate_to_tail);
STAT_ATTR(DEACTIVATE_REMOTE_FREES, deactivate_remote_frees);
-
+STAT_ATTR(ORDER_FALLBACK, order_fallback);
#endif
static struct attribute *slab_attrs[] = {
@@ -4047,6 +4135,8 @@ static struct attribute *slab_attrs[] = {
&objs_per_slab_attr.attr,
&order_attr.attr,
&objects_attr.attr,
+ &objects_partial_attr.attr,
+ &total_objects_attr.attr,
&slabs_attr.attr,
&partial_attr.attr,
&cpu_slabs_attr.attr,
@@ -4089,6 +4179,7 @@ static struct attribute *slab_attrs[] = {
&deactivate_to_head_attr.attr,
&deactivate_to_tail_attr.attr,
&deactivate_remote_frees_attr.attr,
+ &order_fallback_attr.attr,
#endif
NULL
};
@@ -4375,7 +4466,8 @@ static int s_show(struct seq_file *m, void *p)
unsigned long nr_partials = 0;
unsigned long nr_slabs = 0;
unsigned long nr_inuse = 0;
- unsigned long nr_objs;
+ unsigned long nr_objs = 0;
+ unsigned long nr_free = 0;
struct kmem_cache *s;
int node;
@@ -4389,14 +4481,15 @@ static int s_show(struct seq_file *m, void *p)
nr_partials += n->nr_partial;
nr_slabs += atomic_long_read(&n->nr_slabs);
- nr_inuse += count_partial(n);
+ nr_objs += atomic_long_read(&n->total_objects);
+ nr_free += count_partial(n, count_free);
}
- nr_objs = nr_slabs * s->objects;
- nr_inuse += (nr_slabs - nr_partials) * s->objects;
+ nr_inuse = nr_objs - nr_free;
seq_printf(m, "%-17s %6lu %6lu %6u %4u %4d", s->name, nr_inuse,
- nr_objs, s->size, s->objects, (1 << s->order));
+ nr_objs, s->size, oo_objects(s->oo),
+ (1 << oo_order(s->oo)));
seq_printf(m, " : tunables %4u %4u %4u", 0, 0, 0);
seq_printf(m, " : slabdata %6lu %6lu %6lu", nr_slabs, nr_slabs,
0UL);
diff --git a/scripts/gen_initramfs_list.sh b/scripts/gen_initramfs_list.sh
index 684fb9cdc05..5f3415f2873 100644
--- a/scripts/gen_initramfs_list.sh
+++ b/scripts/gen_initramfs_list.sh
@@ -135,7 +135,7 @@ parse() {
str="${ftype} ${name} ${str} ${dev} ${maj} ${min}"
;;
"slink")
- local target=`field 11 $(LC_ALL=C ls -l "${location}")`
+ local target=`readlink "${location}"`
str="${ftype} ${name} ${target} ${str}"
;;
*)
diff --git a/scripts/kconfig/lex.zconf.c_shipped b/scripts/kconfig/lex.zconf.c_shipped
index bed0f4e2d2f..6a61cee4a32 100644
--- a/scripts/kconfig/lex.zconf.c_shipped
+++ b/scripts/kconfig/lex.zconf.c_shipped
@@ -5,25 +5,6 @@
/* A lexical scanner generated by flex */
-#define yy_create_buffer zconf_create_buffer
-#define yy_delete_buffer zconf_delete_buffer
-#define yy_flex_debug zconf_flex_debug
-#define yy_init_buffer zconf_init_buffer
-#define yy_flush_buffer zconf_flush_buffer
-#define yy_load_buffer_state zconf_load_buffer_state
-#define yy_switch_to_buffer zconf_switch_to_buffer
-#define yyin zconfin
-#define yyleng zconfleng
-#define yylex zconflex
-#define yylineno zconflineno
-#define yyout zconfout
-#define yyrestart zconfrestart
-#define yytext zconftext
-#define yywrap zconfwrap
-#define yyalloc zconfalloc
-#define yyrealloc zconfrealloc
-#define yyfree zconffree
-
#define FLEX_SCANNER
#define YY_FLEX_MAJOR_VERSION 2
#define YY_FLEX_MINOR_VERSION 5
@@ -354,7 +335,7 @@ void zconffree (void * );
/* Begin user sect3 */
-#define zconfwrap(n) 1
+#define zconfwrap() 1
#define YY_SKIP_YYWRAP
typedef unsigned char YY_CHAR;
@@ -1535,7 +1516,7 @@ static int yy_get_next_buffer (void)
/* Read in more data. */
YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
- (yy_n_chars), num_to_read );
+ (yy_n_chars), (size_t) num_to_read );
YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
}
@@ -2007,7 +1988,7 @@ YY_BUFFER_STATE zconf_scan_buffer (char * base, yy_size_t size )
/** Setup the input buffer state to scan a string. The next call to zconflex() will
* scan from a @e copy of @a str.
- * @param str a NUL-terminated string to scan
+ * @param yystr a NUL-terminated string to scan
*
* @return the newly allocated buffer state object.
* @note If you want to scan bytes that may contain NUL values, then use
diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h
index 4d09f6ddefe..8e69461313d 100644
--- a/scripts/kconfig/lkc_proto.h
+++ b/scripts/kconfig/lkc_proto.h
@@ -21,7 +21,7 @@ P(menu_get_help,const char *,(struct menu *menu));
/* symbol.c */
P(symbol_hash,struct symbol *,[SYMBOL_HASHSIZE]);
-P(sym_lookup,struct symbol *,(const char *name, int isconst));
+P(sym_lookup,struct symbol *,(const char *name, int flags));
P(sym_find,struct symbol *,(const char *name));
P(sym_re_search,struct symbol **,(const char *pattern));
P(sym_type_name,const char *,(enum symbol_type type));
diff --git a/scripts/kconfig/lxdialog/inputbox.c b/scripts/kconfig/lxdialog/inputbox.c
index 4946bd02b46..616c6013818 100644
--- a/scripts/kconfig/lxdialog/inputbox.c
+++ b/scripts/kconfig/lxdialog/inputbox.c
@@ -89,7 +89,7 @@ do_resize:
box_y = y + 2;
box_x = (width - box_width) / 2;
draw_box(dialog, y + 1, box_x - 1, 3, box_width + 2,
- dlg.border.atr, dlg.dialog.atr);
+ dlg.dialog.atr, dlg.border.atr);
print_buttons(dialog, height, width, 0);
diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c
index 606ceb9e746..07ff8d105c9 100644
--- a/scripts/kconfig/menu.c
+++ b/scripts/kconfig/menu.c
@@ -235,18 +235,22 @@ void menu_finalize(struct menu *parent)
sym = parent->sym;
if (parent->list) {
if (sym && sym_is_choice(sym)) {
- /* find the first choice value and find out choice type */
- for (menu = parent->list; menu; menu = menu->next) {
- if (menu->sym) {
- current_entry = parent;
- if (sym->type == S_UNKNOWN)
+ if (sym->type == S_UNKNOWN) {
+ /* find the first choice value to find out choice type */
+ current_entry = parent;
+ for (menu = parent->list; menu; menu = menu->next) {
+ if (menu->sym && menu->sym->type != S_UNKNOWN) {
menu_set_type(menu->sym->type);
- current_entry = menu;
- if (menu->sym->type == S_UNKNOWN)
- menu_set_type(sym->type);
- break;
+ break;
+ }
}
}
+ /* set the type of the remaining choice values */
+ for (menu = parent->list; menu; menu = menu->next) {
+ current_entry = menu;
+ if (menu->sym && menu->sym->type == S_UNKNOWN)
+ menu_set_type(sym->type);
+ }
parentdep = expr_alloc_symbol(sym);
} else if (parent->prompt)
parentdep = parent->prompt->visible.expr;
@@ -313,50 +317,36 @@ void menu_finalize(struct menu *parent)
}
}
for (menu = parent->list; menu; menu = menu->next) {
- if (sym && sym_is_choice(sym) && menu->sym) {
+ if (sym && sym_is_choice(sym) &&
+ menu->sym && !sym_is_choice_value(menu->sym)) {
+ current_entry = menu;
menu->sym->flags |= SYMBOL_CHOICEVAL;
if (!menu->prompt)
menu_warn(menu, "choice value must have a prompt");
for (prop = menu->sym->prop; prop; prop = prop->next) {
- if (prop->type == P_PROMPT && prop->menu != menu) {
- prop_warn(prop, "choice values "
- "currently only support a "
- "single prompt");
- }
if (prop->type == P_DEFAULT)
prop_warn(prop, "defaults for choice "
- "values not supported");
+ "values not supported");
+ if (prop->menu == menu)
+ continue;
+ if (prop->type == P_PROMPT &&
+ prop->menu->parent->sym != sym)
+ prop_warn(prop, "choice value used outside its choice group");
}
- current_entry = menu;
- if (menu->sym->type == S_UNKNOWN)
- menu_set_type(sym->type);
/* Non-tristate choice values of tristate choices must
* depend on the choice being set to Y. The choice
* values' dependencies were propagated to their
* properties above, so the change here must be re-
- * propagated. */
+ * propagated.
+ */
if (sym->type == S_TRISTATE && menu->sym->type != S_TRISTATE) {
basedep = expr_alloc_comp(E_EQUAL, sym, &symbol_yes);
- basedep = expr_alloc_and(basedep, menu->dep);
- basedep = expr_eliminate_dups(basedep);
- menu->dep = basedep;
+ menu->dep = expr_alloc_and(basedep, menu->dep);
for (prop = menu->sym->prop; prop; prop = prop->next) {
if (prop->menu != menu)
continue;
- dep = expr_alloc_and(expr_copy(basedep),
- prop->visible.expr);
- dep = expr_eliminate_dups(dep);
- dep = expr_trans_bool(dep);
- prop->visible.expr = dep;
- if (prop->type == P_SELECT) {
- struct symbol *es = prop_get_symbol(prop);
- dep2 = expr_alloc_symbol(menu->sym);
- dep = expr_alloc_and(dep2,
- expr_copy(dep));
- dep = expr_alloc_or(es->rev_dep.expr, dep);
- dep = expr_eliminate_dups(dep);
- es->rev_dep.expr = dep;
- }
+ prop->visible.expr = expr_alloc_and(expr_copy(basedep),
+ prop->visible.expr);
}
}
menu_add_symbol(P_CHOICE, sym, NULL);
diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c
index 4a03191ad17..18f3e5c3363 100644
--- a/scripts/kconfig/symbol.c
+++ b/scripts/kconfig/symbol.c
@@ -40,7 +40,7 @@ void sym_add_default(struct symbol *sym, const char *def)
{
struct property *prop = prop_alloc(P_DEFAULT, sym);
- prop->expr = expr_alloc_symbol(sym_lookup(def, 1));
+ prop->expr = expr_alloc_symbol(sym_lookup(def, SYMBOL_CONST));
}
void sym_init(void)
@@ -350,9 +350,6 @@ void sym_calc_value(struct symbol *sym)
;
}
- if (sym->flags & SYMBOL_AUTO)
- sym->flags &= ~SYMBOL_WRITE;
-
sym->curr = newval;
if (sym_is_choice(sym) && newval.tri == yes)
sym->curr.val = sym_calc_choice(sym);
@@ -377,6 +374,9 @@ void sym_calc_value(struct symbol *sym)
sym_set_changed(choice_sym);
}
}
+
+ if (sym->flags & SYMBOL_AUTO)
+ sym->flags &= ~SYMBOL_WRITE;
}
void sym_clear_all_valid(void)
@@ -651,7 +651,7 @@ bool sym_is_changable(struct symbol *sym)
return sym->visible > sym->rev_dep.tri;
}
-struct symbol *sym_lookup(const char *name, int isconst)
+struct symbol *sym_lookup(const char *name, int flags)
{
struct symbol *symbol;
const char *ptr;
@@ -671,11 +671,10 @@ struct symbol *sym_lookup(const char *name, int isconst)
hash &= 0xff;
for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) {
- if (!strcmp(symbol->name, name)) {
- if ((isconst && symbol->flags & SYMBOL_CONST) ||
- (!isconst && !(symbol->flags & SYMBOL_CONST)))
- return symbol;
- }
+ if (!strcmp(symbol->name, name) &&
+ (flags ? symbol->flags & flags
+ : !(symbol->flags & (SYMBOL_CONST|SYMBOL_CHOICE))))
+ return symbol;
}
new_name = strdup(name);
} else {
@@ -687,8 +686,7 @@ struct symbol *sym_lookup(const char *name, int isconst)
memset(symbol, 0, sizeof(*symbol));
symbol->name = new_name;
symbol->type = S_UNKNOWN;
- if (isconst)
- symbol->flags |= SYMBOL_CONST;
+ symbol->flags |= flags;
symbol->next = symbol_hash[hash];
symbol_hash[hash] = symbol;
@@ -762,8 +760,6 @@ struct symbol **sym_re_search(const char *pattern)
}
-struct symbol *sym_check_deps(struct symbol *sym);
-
static struct symbol *sym_check_expr_deps(struct expr *e)
{
struct symbol *sym;
@@ -795,40 +791,100 @@ static struct symbol *sym_check_expr_deps(struct expr *e)
}
/* return NULL when dependencies are OK */
-struct symbol *sym_check_deps(struct symbol *sym)
+static struct symbol *sym_check_sym_deps(struct symbol *sym)
{
struct symbol *sym2;
struct property *prop;
- if (sym->flags & SYMBOL_CHECK) {
- fprintf(stderr, "%s:%d:error: found recursive dependency: %s",
- sym->prop->file->name, sym->prop->lineno, sym->name);
- return sym;
- }
- if (sym->flags & SYMBOL_CHECKED)
- return NULL;
-
- sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED);
sym2 = sym_check_expr_deps(sym->rev_dep.expr);
if (sym2)
- goto out;
+ return sym2;
for (prop = sym->prop; prop; prop = prop->next) {
if (prop->type == P_CHOICE || prop->type == P_SELECT)
continue;
sym2 = sym_check_expr_deps(prop->visible.expr);
if (sym2)
- goto out;
+ break;
if (prop->type != P_DEFAULT || sym_is_choice(sym))
continue;
sym2 = sym_check_expr_deps(prop->expr);
if (sym2)
- goto out;
+ break;
}
-out:
+
+ return sym2;
+}
+
+static struct symbol *sym_check_choice_deps(struct symbol *choice)
+{
+ struct symbol *sym, *sym2;
+ struct property *prop;
+ struct expr *e;
+
+ prop = sym_get_choice_prop(choice);
+ expr_list_for_each_sym(prop->expr, e, sym)
+ sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED);
+
+ choice->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED);
+ sym2 = sym_check_sym_deps(choice);
+ choice->flags &= ~SYMBOL_CHECK;
if (sym2)
- fprintf(stderr, " -> %s%s", sym->name, sym2 == sym? "\n": "");
- sym->flags &= ~SYMBOL_CHECK;
+ goto out;
+
+ expr_list_for_each_sym(prop->expr, e, sym) {
+ sym2 = sym_check_sym_deps(sym);
+ if (sym2) {
+ fprintf(stderr, " -> %s", sym->name);
+ break;
+ }
+ }
+out:
+ expr_list_for_each_sym(prop->expr, e, sym)
+ sym->flags &= ~SYMBOL_CHECK;
+
+ if (sym2 && sym_is_choice_value(sym2) &&
+ prop_get_symbol(sym_get_choice_prop(sym2)) == choice)
+ sym2 = choice;
+
+ return sym2;
+}
+
+struct symbol *sym_check_deps(struct symbol *sym)
+{
+ struct symbol *sym2;
+ struct property *prop;
+
+ if (sym->flags & SYMBOL_CHECK) {
+ fprintf(stderr, "%s:%d:error: found recursive dependency: %s",
+ sym->prop->file->name, sym->prop->lineno,
+ sym->name ? sym->name : "<choice>");
+ return sym;
+ }
+ if (sym->flags & SYMBOL_CHECKED)
+ return NULL;
+
+ if (sym_is_choice_value(sym)) {
+ /* for choice groups start the check with main choice symbol */
+ prop = sym_get_choice_prop(sym);
+ sym2 = sym_check_deps(prop_get_symbol(prop));
+ } else if (sym_is_choice(sym)) {
+ sym2 = sym_check_choice_deps(sym);
+ } else {
+ sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED);
+ sym2 = sym_check_sym_deps(sym);
+ sym->flags &= ~SYMBOL_CHECK;
+ }
+
+ if (sym2) {
+ fprintf(stderr, " -> %s", sym->name ? sym->name : "<choice>");
+ if (sym2 == sym) {
+ fprintf(stderr, "\n");
+ zconfnerrs++;
+ sym2 = NULL;
+ }
+ }
+
return sym2;
}
@@ -904,7 +960,7 @@ void prop_add_env(const char *env)
}
prop = prop_alloc(P_ENV, sym);
- prop->expr = expr_alloc_symbol(sym_lookup(env, 1));
+ prop->expr = expr_alloc_symbol(sym_lookup(env, SYMBOL_CONST));
sym_env_list = expr_alloc_one(E_LIST, sym_env_list);
sym_env_list->right.sym = sym;
diff --git a/scripts/kconfig/zconf.tab.c_shipped b/scripts/kconfig/zconf.tab.c_shipped
index d22d92496f2..95df833b5a9 100644
--- a/scripts/kconfig/zconf.tab.c_shipped
+++ b/scripts/kconfig/zconf.tab.c_shipped
@@ -446,16 +446,16 @@ union yyalloc
/* YYFINAL -- State number of the termination state. */
#define YYFINAL 3
/* YYLAST -- Last index in YYTABLE. */
-#define YYLAST 258
+#define YYLAST 259
/* YYNTOKENS -- Number of terminals. */
#define YYNTOKENS 35
/* YYNNTS -- Number of nonterminals. */
-#define YYNNTS 45
+#define YYNNTS 46
/* YYNRULES -- Number of rules. */
-#define YYNRULES 108
+#define YYNRULES 110
/* YYNRULES -- Number of states. */
-#define YYNSTATES 178
+#define YYNSTATES 180
/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
#define YYUNDEFTOK 2
@@ -507,13 +507,14 @@ static const yytype_uint16 yyprhs[] =
28, 33, 37, 39, 41, 43, 45, 47, 49, 51,
53, 55, 57, 59, 61, 63, 67, 70, 74, 77,
81, 84, 85, 88, 91, 94, 97, 100, 103, 107,
- 112, 117, 122, 128, 132, 133, 137, 138, 141, 144,
- 147, 149, 153, 154, 157, 160, 163, 166, 169, 174,
- 178, 181, 186, 187, 190, 194, 196, 200, 201, 204,
- 207, 210, 214, 217, 219, 223, 224, 227, 230, 233,
- 237, 241, 244, 247, 250, 251, 254, 257, 260, 265,
- 266, 269, 271, 273, 276, 279, 282, 284, 287, 288,
- 291, 293, 297, 301, 305, 308, 312, 316, 318
+ 112, 117, 122, 128, 132, 133, 137, 138, 141, 145,
+ 148, 150, 154, 155, 158, 161, 164, 167, 170, 175,
+ 179, 182, 187, 188, 191, 195, 197, 201, 202, 205,
+ 208, 211, 215, 218, 220, 224, 225, 228, 231, 234,
+ 238, 242, 245, 248, 251, 252, 255, 258, 261, 266,
+ 267, 270, 272, 274, 277, 280, 283, 285, 288, 289,
+ 292, 294, 298, 302, 306, 309, 313, 317, 319, 321,
+ 322
};
/* YYRHS -- A `-1'-separated list of the rules' RHS. */
@@ -533,24 +534,25 @@ static const yytype_int8 yyrhs[] =
30, -1, 20, 78, 77, 30, -1, 21, 25, 77,
30, -1, 22, 79, 79, 77, 30, -1, 23, 48,
30, -1, -1, 48, 25, 49, -1, -1, 33, 74,
- -1, 7, 30, -1, 50, 54, -1, 75, -1, 51,
- 56, 52, -1, -1, 54, 55, -1, 54, 72, -1,
- 54, 70, -1, 54, 30, -1, 54, 40, -1, 18,
- 74, 77, 30, -1, 19, 73, 30, -1, 17, 30,
- -1, 20, 25, 77, 30, -1, -1, 56, 39, -1,
- 14, 78, 76, -1, 75, -1, 57, 60, 58, -1,
- -1, 60, 39, -1, 60, 64, -1, 60, 53, -1,
- 4, 74, 30, -1, 61, 71, -1, 75, -1, 62,
- 65, 63, -1, -1, 65, 39, -1, 65, 64, -1,
- 65, 53, -1, 6, 74, 30, -1, 9, 74, 30,
- -1, 67, 71, -1, 12, 30, -1, 69, 13, -1,
- -1, 71, 72, -1, 71, 30, -1, 71, 40, -1,
- 16, 24, 78, 30, -1, -1, 74, 77, -1, 25,
- -1, 26, -1, 5, 30, -1, 8, 30, -1, 15,
- 30, -1, 30, -1, 76, 30, -1, -1, 14, 78,
- -1, 79, -1, 79, 33, 79, -1, 79, 27, 79,
- -1, 29, 78, 28, -1, 34, 78, -1, 78, 31,
- 78, -1, 78, 32, 78, -1, 25, -1, 26, -1
+ -1, 7, 80, 30, -1, 50, 54, -1, 75, -1,
+ 51, 56, 52, -1, -1, 54, 55, -1, 54, 72,
+ -1, 54, 70, -1, 54, 30, -1, 54, 40, -1,
+ 18, 74, 77, 30, -1, 19, 73, 30, -1, 17,
+ 30, -1, 20, 25, 77, 30, -1, -1, 56, 39,
+ -1, 14, 78, 76, -1, 75, -1, 57, 60, 58,
+ -1, -1, 60, 39, -1, 60, 64, -1, 60, 53,
+ -1, 4, 74, 30, -1, 61, 71, -1, 75, -1,
+ 62, 65, 63, -1, -1, 65, 39, -1, 65, 64,
+ -1, 65, 53, -1, 6, 74, 30, -1, 9, 74,
+ 30, -1, 67, 71, -1, 12, 30, -1, 69, 13,
+ -1, -1, 71, 72, -1, 71, 30, -1, 71, 40,
+ -1, 16, 24, 78, 30, -1, -1, 74, 77, -1,
+ 25, -1, 26, -1, 5, 30, -1, 8, 30, -1,
+ 15, 30, -1, 30, -1, 76, 30, -1, -1, 14,
+ 78, -1, 79, -1, 79, 33, 79, -1, 79, 27,
+ 79, -1, 29, 78, 28, -1, 34, 78, -1, 78,
+ 31, 78, -1, 78, 32, 78, -1, 25, -1, 26,
+ -1, -1, 25, -1
};
/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
@@ -566,7 +568,8 @@ static const yytype_uint16 yyrline[] =
339, 344, 351, 356, 364, 367, 369, 370, 371, 374,
382, 389, 396, 402, 409, 411, 412, 413, 416, 424,
426, 431, 432, 435, 436, 437, 441, 442, 445, 446,
- 449, 450, 451, 452, 453, 454, 455, 458, 459
+ 449, 450, 451, 452, 453, 454, 455, 458, 459, 462,
+ 463
};
#endif
@@ -590,7 +593,8 @@ static const char *const yytname[] =
"if_entry", "if_end", "if_stmt", "if_block", "menu", "menu_entry",
"menu_end", "menu_stmt", "menu_block", "source_stmt", "comment",
"comment_stmt", "help_start", "help", "depends_list", "depends",
- "prompt_stmt_opt", "prompt", "end", "nl", "if_expr", "expr", "symbol", 0
+ "prompt_stmt_opt", "prompt", "end", "nl", "if_expr", "expr", "symbol",
+ "word_opt", 0
};
#endif
@@ -619,7 +623,8 @@ static const yytype_uint8 yyr1[] =
60, 61, 62, 63, 64, 65, 65, 65, 65, 66,
67, 68, 69, 70, 71, 71, 71, 71, 72, 73,
73, 74, 74, 75, 75, 75, 76, 76, 77, 77,
- 78, 78, 78, 78, 78, 78, 78, 79, 79
+ 78, 78, 78, 78, 78, 78, 78, 79, 79, 80,
+ 80
};
/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
@@ -629,13 +634,14 @@ static const yytype_uint8 yyr2[] =
4, 3, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 3, 2, 3, 2, 3,
2, 0, 2, 2, 2, 2, 2, 2, 3, 4,
- 4, 4, 5, 3, 0, 3, 0, 2, 2, 2,
+ 4, 4, 5, 3, 0, 3, 0, 2, 3, 2,
1, 3, 0, 2, 2, 2, 2, 2, 4, 3,
2, 4, 0, 2, 3, 1, 3, 0, 2, 2,
2, 3, 2, 1, 3, 0, 2, 2, 2, 3,
3, 2, 2, 2, 0, 2, 2, 2, 4, 0,
2, 1, 1, 2, 2, 2, 1, 2, 0, 2,
- 1, 3, 3, 3, 2, 3, 3, 1, 1
+ 1, 3, 3, 3, 2, 3, 3, 1, 1, 0,
+ 1
};
/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
@@ -643,69 +649,69 @@ static const yytype_uint8 yyr2[] =
means the default is an error. */
static const yytype_uint8 yydefact[] =
{
- 3, 0, 0, 1, 0, 0, 0, 0, 0, 0,
+ 3, 0, 0, 1, 0, 0, 0, 0, 0, 109,
0, 0, 0, 0, 0, 0, 12, 16, 13, 14,
18, 15, 17, 0, 19, 0, 4, 31, 22, 31,
23, 52, 62, 5, 67, 20, 84, 75, 6, 24,
84, 21, 8, 11, 91, 92, 0, 0, 93, 0,
- 48, 94, 0, 0, 0, 107, 108, 0, 0, 0,
- 100, 95, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 96, 7, 71, 79, 80, 27, 29, 0,
- 104, 0, 0, 64, 0, 0, 9, 10, 0, 0,
- 0, 0, 89, 0, 0, 0, 44, 0, 37, 36,
- 32, 33, 0, 35, 34, 0, 0, 89, 0, 56,
- 57, 53, 55, 54, 63, 51, 50, 68, 70, 66,
- 69, 65, 86, 87, 85, 76, 78, 74, 77, 73,
- 97, 103, 105, 106, 102, 101, 26, 82, 0, 98,
- 0, 98, 98, 98, 0, 0, 0, 83, 60, 98,
- 0, 98, 0, 0, 0, 38, 90, 0, 0, 98,
- 46, 43, 25, 0, 59, 0, 88, 99, 39, 40,
- 41, 0, 0, 45, 58, 61, 42, 47
+ 110, 0, 94, 0, 0, 0, 107, 108, 0, 0,
+ 0, 100, 95, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 96, 7, 71, 79, 48, 80, 27,
+ 29, 0, 104, 0, 0, 64, 0, 0, 9, 10,
+ 0, 0, 0, 0, 89, 0, 0, 0, 44, 0,
+ 37, 36, 32, 33, 0, 35, 34, 0, 0, 89,
+ 0, 56, 57, 53, 55, 54, 63, 51, 50, 68,
+ 70, 66, 69, 65, 86, 87, 85, 76, 78, 74,
+ 77, 73, 97, 103, 105, 106, 102, 101, 26, 82,
+ 0, 98, 0, 98, 98, 98, 0, 0, 0, 83,
+ 60, 98, 0, 98, 0, 0, 0, 38, 90, 0,
+ 0, 98, 46, 43, 25, 0, 59, 0, 88, 99,
+ 39, 40, 41, 0, 0, 45, 58, 61, 42, 47
};
/* YYDEFGOTO[NTERM-NUM]. */
static const yytype_int16 yydefgoto[] =
{
- -1, 1, 2, 25, 26, 99, 27, 28, 29, 30,
- 64, 100, 101, 145, 173, 31, 32, 115, 33, 66,
- 111, 67, 34, 119, 35, 68, 36, 37, 127, 38,
- 70, 39, 40, 41, 102, 103, 69, 104, 140, 141,
- 42, 73, 154, 59, 60
+ -1, 1, 2, 25, 26, 101, 27, 28, 29, 30,
+ 65, 102, 103, 147, 175, 31, 32, 117, 33, 67,
+ 113, 68, 34, 121, 35, 69, 36, 37, 129, 38,
+ 71, 39, 40, 41, 104, 105, 70, 106, 142, 143,
+ 42, 74, 156, 60, 61, 51
};
/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
STATE-NUM. */
-#define YYPACT_NINF -78
+#define YYPACT_NINF -80
static const yytype_int16 yypact[] =
{
- -78, 33, 130, -78, -28, 73, 73, 7, 73, 36,
- 41, 73, 26, 52, -4, 58, -78, -78, -78, -78,
- -78, -78, -78, 90, -78, 94, -78, -78, -78, -78,
- -78, -78, -78, -78, -78, -78, -78, -78, -78, -78,
- -78, -78, -78, -78, -78, -78, 74, 85, -78, 96,
- -78, -78, 131, 134, 147, -78, -78, -4, -4, 193,
- -10, -78, 162, 164, 38, 102, 64, 148, 5, 192,
- 5, 165, -78, 174, -78, -78, -78, -78, -78, 65,
- -78, -4, -4, 174, 103, 103, -78, -78, 175, 185,
- 197, 73, 73, -4, 194, 103, -78, 231, -78, -78,
- -78, -78, 220, -78, -78, 204, 73, 73, 210, -78,
- -78, -78, -78, -78, -78, -78, -78, -78, -78, -78,
- -78, -78, -78, -78, -78, -78, -78, -78, -78, -78,
- -78, -78, 205, -78, -78, -78, -78, -78, -4, 222,
- 208, 222, 195, 222, 103, 2, 209, -78, -78, 222,
- 211, 222, 199, -4, 212, -78, -78, 213, 214, 222,
- 207, -78, -78, 215, -78, 216, -78, 111, -78, -78,
- -78, 217, 73, -78, -78, -78, -78, -78
+ -80, 2, 132, -80, -13, -1, -1, -2, -1, 9,
+ 33, -1, 27, 40, -3, 38, -80, -80, -80, -80,
+ -80, -80, -80, 71, -80, 77, -80, -80, -80, -80,
+ -80, -80, -80, -80, -80, -80, -80, -80, -80, -80,
+ -80, -80, -80, -80, -80, -80, 57, 61, -80, 63,
+ -80, 76, -80, 87, 101, 133, -80, -80, -3, -3,
+ 195, -6, -80, 136, 149, 39, 104, 65, 150, 5,
+ 194, 5, 167, -80, 176, -80, -80, -80, -80, -80,
+ -80, 68, -80, -3, -3, 176, 72, 72, -80, -80,
+ 177, 187, 78, -1, -1, -3, 196, 72, -80, 222,
+ -80, -80, -80, -80, 221, -80, -80, 205, -1, -1,
+ 211, -80, -80, -80, -80, -80, -80, -80, -80, -80,
+ -80, -80, -80, -80, -80, -80, -80, -80, -80, -80,
+ -80, -80, -80, -80, 206, -80, -80, -80, -80, -80,
+ -3, 223, 209, 223, 197, 223, 72, 7, 210, -80,
+ -80, 223, 212, 223, 201, -3, 213, -80, -80, 214,
+ 215, 223, 208, -80, -80, 216, -80, 217, -80, 113,
+ -80, -80, -80, 218, -1, -80, -80, -80, -80, -80
};
/* YYPGOTO[NTERM-NUM]. */
static const yytype_int16 yypgoto[] =
{
- -78, -78, -78, -78, 121, -35, -78, -78, -78, -78,
- 219, -78, -78, -78, -78, -78, -78, -78, -44, -78,
- -78, -78, -78, -78, -78, -78, -78, -78, -78, -6,
- -78, -78, -78, -78, -78, 183, 218, 21, 143, -5,
- 146, 196, 69, -53, -77
+ -80, -80, -80, -80, 122, -34, -80, -80, -80, -80,
+ 220, -80, -80, -80, -80, -80, -80, -80, 59, -80,
+ -80, -80, -80, -80, -80, -80, -80, -80, -80, 125,
+ -80, -80, -80, -80, -80, 183, 219, 22, 142, -5,
+ 147, 192, 69, -54, -79, -80
};
/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
@@ -715,62 +721,62 @@ static const yytype_int16 yypgoto[] =
#define YYTABLE_NINF -82
static const yytype_int16 yytable[] =
{
- 46, 47, 43, 49, 79, 80, 52, 134, 135, 6,
- 7, 8, 9, 10, 11, 12, 13, 84, 144, 14,
- 15, 55, 56, 85, 118, 57, 126, 160, 132, 133,
- 58, 110, 161, 3, 123, 24, 123, 48, -28, 88,
- 142, -28, -28, -28, -28, -28, -28, -28, -28, -28,
- 89, 53, -28, -28, 90, -28, 91, 92, 93, 94,
- 95, 96, 120, 97, 128, 88, 50, 159, 98, -49,
- -49, 51, -49, -49, -49, -49, 89, 54, -49, -49,
- 90, 105, 106, 107, 108, 152, 139, 113, 61, 97,
- 124, 62, 124, 131, 109, 63, 81, 82, 44, 45,
- 167, 149, -30, 88, 72, -30, -30, -30, -30, -30,
- -30, -30, -30, -30, 89, 74, -30, -30, 90, -30,
- 91, 92, 93, 94, 95, 96, 75, 97, 55, 56,
- -2, 4, 98, 5, 6, 7, 8, 9, 10, 11,
- 12, 13, 81, 82, 14, 15, 16, 17, 18, 19,
- 20, 21, 22, 7, 8, 23, 10, 11, 12, 13,
- 24, 76, 14, 15, 77, -81, 88, 177, -81, -81,
- -81, -81, -81, -81, -81, -81, -81, 78, 24, -81,
- -81, 90, -81, -81, -81, -81, -81, -81, 114, 117,
- 97, 125, 86, 88, 87, 122, -72, -72, -72, -72,
- -72, -72, -72, -72, 130, 136, -72, -72, 90, 153,
- 156, 157, 158, 116, 121, 137, 129, 97, 163, 143,
- 165, 138, 122, 72, 81, 82, 81, 82, 171, 166,
- 81, 82, 146, 147, 148, 151, 153, 82, 155, 162,
- 172, 164, 168, 169, 170, 174, 175, 176, 65, 112,
- 150, 0, 0, 0, 0, 83, 0, 0, 71
+ 46, 47, 3, 49, 81, 82, 53, 136, 137, 6,
+ 7, 8, 9, 10, 11, 12, 13, 43, 146, 14,
+ 15, 86, 56, 57, 44, 45, 58, 87, 48, 134,
+ 135, 59, 162, 112, 50, 24, 125, 163, 125, -28,
+ 90, 144, -28, -28, -28, -28, -28, -28, -28, -28,
+ -28, 91, 54, -28, -28, 92, -28, 93, 94, 95,
+ 96, 97, 98, 52, 99, 55, 90, 161, 62, 100,
+ -49, -49, 63, -49, -49, -49, -49, 91, 64, -49,
+ -49, 92, 107, 108, 109, 110, 154, 73, 141, 115,
+ 99, 75, 126, 76, 126, 111, 133, 56, 57, 83,
+ 84, 169, 140, 151, -30, 90, 77, -30, -30, -30,
+ -30, -30, -30, -30, -30, -30, 91, 78, -30, -30,
+ 92, -30, 93, 94, 95, 96, 97, 98, 120, 99,
+ 128, 79, -2, 4, 100, 5, 6, 7, 8, 9,
+ 10, 11, 12, 13, 83, 84, 14, 15, 16, 17,
+ 18, 19, 20, 21, 22, 7, 8, 23, 10, 11,
+ 12, 13, 24, 80, 14, 15, 88, -81, 90, 179,
+ -81, -81, -81, -81, -81, -81, -81, -81, -81, 89,
+ 24, -81, -81, 92, -81, -81, -81, -81, -81, -81,
+ 116, 119, 99, 127, 122, 90, 130, 124, -72, -72,
+ -72, -72, -72, -72, -72, -72, 132, 138, -72, -72,
+ 92, 155, 158, 159, 160, 118, 123, 139, 131, 99,
+ 165, 145, 167, 148, 124, 73, 83, 84, 83, 84,
+ 173, 168, 83, 84, 149, 150, 153, 155, 84, 157,
+ 164, 174, 166, 170, 171, 172, 176, 177, 178, 66,
+ 114, 152, 85, 0, 0, 0, 0, 0, 0, 72
};
static const yytype_int16 yycheck[] =
{
- 5, 6, 30, 8, 57, 58, 11, 84, 85, 4,
- 5, 6, 7, 8, 9, 10, 11, 27, 95, 14,
- 15, 25, 26, 33, 68, 29, 70, 25, 81, 82,
- 34, 66, 30, 0, 69, 30, 71, 30, 0, 1,
- 93, 3, 4, 5, 6, 7, 8, 9, 10, 11,
- 12, 25, 14, 15, 16, 17, 18, 19, 20, 21,
- 22, 23, 68, 25, 70, 1, 30, 144, 30, 5,
- 6, 30, 8, 9, 10, 11, 12, 25, 14, 15,
- 16, 17, 18, 19, 20, 138, 91, 66, 30, 25,
- 69, 1, 71, 28, 30, 1, 31, 32, 25, 26,
- 153, 106, 0, 1, 30, 3, 4, 5, 6, 7,
- 8, 9, 10, 11, 12, 30, 14, 15, 16, 17,
- 18, 19, 20, 21, 22, 23, 30, 25, 25, 26,
- 0, 1, 30, 3, 4, 5, 6, 7, 8, 9,
- 10, 11, 31, 32, 14, 15, 16, 17, 18, 19,
- 20, 21, 22, 5, 6, 25, 8, 9, 10, 11,
- 30, 30, 14, 15, 30, 0, 1, 172, 3, 4,
- 5, 6, 7, 8, 9, 10, 11, 30, 30, 14,
- 15, 16, 17, 18, 19, 20, 21, 22, 67, 68,
- 25, 70, 30, 1, 30, 30, 4, 5, 6, 7,
- 8, 9, 10, 11, 30, 30, 14, 15, 16, 14,
- 141, 142, 143, 67, 68, 30, 70, 25, 149, 25,
- 151, 24, 30, 30, 31, 32, 31, 32, 159, 30,
- 31, 32, 1, 13, 30, 25, 14, 32, 30, 30,
- 33, 30, 30, 30, 30, 30, 30, 30, 29, 66,
- 107, -1, -1, -1, -1, 59, -1, -1, 40
+ 5, 6, 0, 8, 58, 59, 11, 86, 87, 4,
+ 5, 6, 7, 8, 9, 10, 11, 30, 97, 14,
+ 15, 27, 25, 26, 25, 26, 29, 33, 30, 83,
+ 84, 34, 25, 67, 25, 30, 70, 30, 72, 0,
+ 1, 95, 3, 4, 5, 6, 7, 8, 9, 10,
+ 11, 12, 25, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 23, 30, 25, 25, 1, 146, 30, 30,
+ 5, 6, 1, 8, 9, 10, 11, 12, 1, 14,
+ 15, 16, 17, 18, 19, 20, 140, 30, 93, 67,
+ 25, 30, 70, 30, 72, 30, 28, 25, 26, 31,
+ 32, 155, 24, 108, 0, 1, 30, 3, 4, 5,
+ 6, 7, 8, 9, 10, 11, 12, 30, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 69, 25,
+ 71, 30, 0, 1, 30, 3, 4, 5, 6, 7,
+ 8, 9, 10, 11, 31, 32, 14, 15, 16, 17,
+ 18, 19, 20, 21, 22, 5, 6, 25, 8, 9,
+ 10, 11, 30, 30, 14, 15, 30, 0, 1, 174,
+ 3, 4, 5, 6, 7, 8, 9, 10, 11, 30,
+ 30, 14, 15, 16, 17, 18, 19, 20, 21, 22,
+ 68, 69, 25, 71, 69, 1, 71, 30, 4, 5,
+ 6, 7, 8, 9, 10, 11, 30, 30, 14, 15,
+ 16, 14, 143, 144, 145, 68, 69, 30, 71, 25,
+ 151, 25, 153, 1, 30, 30, 31, 32, 31, 32,
+ 161, 30, 31, 32, 13, 30, 25, 14, 32, 30,
+ 30, 33, 30, 30, 30, 30, 30, 30, 30, 29,
+ 67, 109, 60, -1, -1, -1, -1, -1, -1, 40
};
/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
@@ -782,19 +788,19 @@ static const yytype_uint8 yystos[] =
20, 21, 22, 25, 30, 38, 39, 41, 42, 43,
44, 50, 51, 53, 57, 59, 61, 62, 64, 66,
67, 68, 75, 30, 25, 26, 74, 74, 30, 74,
- 30, 30, 74, 25, 25, 25, 26, 29, 34, 78,
- 79, 30, 1, 1, 45, 45, 54, 56, 60, 71,
- 65, 71, 30, 76, 30, 30, 30, 30, 30, 78,
- 78, 31, 32, 76, 27, 33, 30, 30, 1, 12,
- 16, 18, 19, 20, 21, 22, 23, 25, 30, 40,
- 46, 47, 69, 70, 72, 17, 18, 19, 20, 30,
- 40, 55, 70, 72, 39, 52, 75, 39, 53, 58,
- 64, 75, 30, 40, 72, 39, 53, 63, 64, 75,
- 30, 28, 78, 78, 79, 79, 30, 30, 24, 74,
- 73, 74, 78, 25, 79, 48, 1, 13, 30, 74,
- 73, 25, 78, 14, 77, 30, 77, 77, 77, 79,
- 25, 30, 30, 77, 30, 77, 30, 78, 30, 30,
- 30, 77, 33, 49, 30, 30, 30, 74
+ 25, 80, 30, 74, 25, 25, 25, 26, 29, 34,
+ 78, 79, 30, 1, 1, 45, 45, 54, 56, 60,
+ 71, 65, 71, 30, 76, 30, 30, 30, 30, 30,
+ 30, 78, 78, 31, 32, 76, 27, 33, 30, 30,
+ 1, 12, 16, 18, 19, 20, 21, 22, 23, 25,
+ 30, 40, 46, 47, 69, 70, 72, 17, 18, 19,
+ 20, 30, 40, 55, 70, 72, 39, 52, 75, 39,
+ 53, 58, 64, 75, 30, 40, 72, 39, 53, 63,
+ 64, 75, 30, 28, 78, 78, 79, 79, 30, 30,
+ 24, 74, 73, 74, 78, 25, 79, 48, 1, 13,
+ 30, 74, 73, 25, 78, 14, 77, 30, 77, 77,
+ 77, 79, 25, 30, 30, 77, 30, 77, 30, 78,
+ 30, 30, 30, 77, 33, 49, 30, 30, 30, 74
};
#define yyerrok (yyerrstatus = 0)
@@ -1781,8 +1787,8 @@ yyreduce:
case 48:
{
- struct symbol *sym = sym_lookup(NULL, 0);
- sym->flags |= SYMBOL_CHOICE;
+ struct symbol *sym = sym_lookup((yyvsp[(2) - (3)].string), SYMBOL_CHOICE);
+ sym->flags |= SYMBOL_AUTO;
menu_add_entry(sym);
menu_add_expr(P_CHOICE, NULL, NULL);
printd(DEBUG_PARSE, "%s:%d:choice\n", zconf_curname(), zconf_lineno());
@@ -2014,7 +2020,12 @@ yyreduce:
case 108:
- { (yyval.symbol) = sym_lookup((yyvsp[(1) - (1)].string), 1); free((yyvsp[(1) - (1)].string)); ;}
+ { (yyval.symbol) = sym_lookup((yyvsp[(1) - (1)].string), SYMBOL_CONST); free((yyvsp[(1) - (1)].string)); ;}
+ break;
+
+ case 109:
+
+ { (yyval.string) = NULL; ;}
break;
diff --git a/scripts/kconfig/zconf.y b/scripts/kconfig/zconf.y
index d9b96ba8e38..9710b82466f 100644
--- a/scripts/kconfig/zconf.y
+++ b/scripts/kconfig/zconf.y
@@ -91,7 +91,7 @@ static struct menu *current_menu, *current_entry;
%type <id> end
%type <id> option_name
%type <menu> if_entry menu_entry choice_entry
-%type <string> symbol_option_arg
+%type <string> symbol_option_arg word_opt
%destructor {
fprintf(stderr, "%s:%d: missing end statement for this entry\n",
@@ -239,10 +239,10 @@ symbol_option_arg:
/* choice entry */
-choice: T_CHOICE T_EOL
+choice: T_CHOICE word_opt T_EOL
{
- struct symbol *sym = sym_lookup(NULL, 0);
- sym->flags |= SYMBOL_CHOICE;
+ struct symbol *sym = sym_lookup($2, SYMBOL_CHOICE);
+ sym->flags |= SYMBOL_AUTO;
menu_add_entry(sym);
menu_add_expr(P_CHOICE, NULL, NULL);
printd(DEBUG_PARSE, "%s:%d:choice\n", zconf_curname(), zconf_lineno());
@@ -456,9 +456,12 @@ expr: symbol { $$ = expr_alloc_symbol($1); }
;
symbol: T_WORD { $$ = sym_lookup($1, 0); free($1); }
- | T_WORD_QUOTE { $$ = sym_lookup($1, 1); free($1); }
+ | T_WORD_QUOTE { $$ = sym_lookup($1, SYMBOL_CONST); free($1); }
;
+word_opt: /* empty */ { $$ = NULL; }
+ | T_WORD
+
%%
void conf_parse(const char *name)