]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - kernel/cpuset.c
[PATCH] autofs4: autofs4_follow_link false negative fix
[linux-2.6-omap-h63xx.git] / kernel / cpuset.c
index 1a649f2bb9bb2779fb2a033dda7eba5898da596b..584bb4e6c0421cb5e25b5a68f2f694accad4383a 100644 (file)
@@ -240,7 +240,7 @@ static struct super_block *cpuset_sb;
  * A cpuset can only be deleted if both its 'count' of using tasks
  * is zero, and its list of 'children' cpusets is empty.  Since all
  * tasks in the system use _some_ cpuset, and since there is always at
- * least one task in the system (init, pid == 1), therefore, top_cpuset
+ * least one task in the system (init), therefore, top_cpuset
  * always has either children cpusets and/or using tasks.  So we don't
  * need a special hack to ensure that top_cpuset cannot be deleted.
  *
@@ -289,7 +289,6 @@ static struct inode *cpuset_new_inode(mode_t mode)
                inode->i_mode = mode;
                inode->i_uid = current->fsuid;
                inode->i_gid = current->fsgid;
-               inode->i_blksize = PAGE_CACHE_SIZE;
                inode->i_blocks = 0;
                inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
                inode->i_mapping->backing_dev_info = &cpuset_backing_dev_info;
@@ -816,6 +815,10 @@ static int update_cpumask(struct cpuset *cs, char *buf)
        struct cpuset trialcs;
        int retval, cpus_unchanged;
 
+       /* top_cpuset.cpus_allowed tracks cpu_online_map; it's read-only */
+       if (cs == &top_cpuset)
+               return -EACCES;
+
        trialcs = *cs;
        retval = cpulist_parse(buf, trialcs.cpus_allowed);
        if (retval < 0)
@@ -2033,6 +2036,33 @@ out:
        return err;
 }
 
+/*
+ * The top_cpuset tracks what CPUs and Memory Nodes are online,
+ * period.  This is necessary in order to make cpusets transparent
+ * (of no affect) on systems that are actively using CPU hotplug
+ * but making no active use of cpusets.
+ *
+ * This handles CPU hotplug (cpuhp) events.  If someday Memory
+ * Nodes can be hotplugged (dynamically changing node_online_map)
+ * then we should handle that too, perhaps in a similar way.
+ */
+
+#ifdef CONFIG_HOTPLUG_CPU
+static int cpuset_handle_cpuhp(struct notifier_block *nb,
+                               unsigned long phase, void *cpu)
+{
+       mutex_lock(&manage_mutex);
+       mutex_lock(&callback_mutex);
+
+       top_cpuset.cpus_allowed = cpu_online_map;
+
+       mutex_unlock(&callback_mutex);
+       mutex_unlock(&manage_mutex);
+
+       return 0;
+}
+#endif
+
 /**
  * cpuset_init_smp - initialize cpus_allowed
  *
@@ -2043,6 +2073,8 @@ void __init cpuset_init_smp(void)
 {
        top_cpuset.cpus_allowed = cpu_online_map;
        top_cpuset.mems_allowed = node_online_map;
+
+       hotcpu_notifier(cpuset_handle_cpuhp, 0);
 }
 
 /**
@@ -2212,7 +2244,7 @@ int cpuset_zonelist_valid_mems_allowed(struct zonelist *zl)
        int i;
 
        for (i = 0; zl->zones[i]; i++) {
-               int nid = zl->zones[i]->zone_pgdat->node_id;
+               int nid = zone_to_nid(zl->zones[i]);
 
                if (node_isset(nid, current->mems_allowed))
                        return 1;
@@ -2283,9 +2315,9 @@ int __cpuset_zone_allowed(struct zone *z, gfp_t gfp_mask)
        const struct cpuset *cs;        /* current cpuset ancestors */
        int allowed;                    /* is allocation in zone z allowed? */
 
-       if (in_interrupt())
+       if (in_interrupt() || (gfp_mask & __GFP_THISNODE))
                return 1;
-       node = z->zone_pgdat->node_id;
+       node = zone_to_nid(z);
        might_sleep_if(!(gfp_mask & __GFP_HARDWALL));
        if (node_isset(node, current->mems_allowed))
                return 1;
@@ -2387,7 +2419,7 @@ EXPORT_SYMBOL_GPL(cpuset_mem_spread_node);
 int cpuset_excl_nodes_overlap(const struct task_struct *p)
 {
        const struct cpuset *cs1, *cs2; /* my and p's cpuset ancestors */
-       int overlap = 0;                /* do cpusets overlap? */
+       int overlap = 1;                /* do cpusets overlap? */
 
        task_lock(current);
        if (current->flags & PF_EXITING) {