net/mlx5: Update error handler for UCTX and UMEM
[linux-2.6-microblaze.git] / mm / mempolicy.c
index f4b4be7..10e9c87 100644 (file)
@@ -2206,6 +2206,88 @@ struct folio *folio_alloc(gfp_t gfp, unsigned order)
 }
 EXPORT_SYMBOL(folio_alloc);
 
+static unsigned long alloc_pages_bulk_array_interleave(gfp_t gfp,
+               struct mempolicy *pol, unsigned long nr_pages,
+               struct page **page_array)
+{
+       int nodes;
+       unsigned long nr_pages_per_node;
+       int delta;
+       int i;
+       unsigned long nr_allocated;
+       unsigned long total_allocated = 0;
+
+       nodes = nodes_weight(pol->nodes);
+       nr_pages_per_node = nr_pages / nodes;
+       delta = nr_pages - nodes * nr_pages_per_node;
+
+       for (i = 0; i < nodes; i++) {
+               if (delta) {
+                       nr_allocated = __alloc_pages_bulk(gfp,
+                                       interleave_nodes(pol), NULL,
+                                       nr_pages_per_node + 1, NULL,
+                                       page_array);
+                       delta--;
+               } else {
+                       nr_allocated = __alloc_pages_bulk(gfp,
+                                       interleave_nodes(pol), NULL,
+                                       nr_pages_per_node, NULL, page_array);
+               }
+
+               page_array += nr_allocated;
+               total_allocated += nr_allocated;
+       }
+
+       return total_allocated;
+}
+
+static unsigned long alloc_pages_bulk_array_preferred_many(gfp_t gfp, int nid,
+               struct mempolicy *pol, unsigned long nr_pages,
+               struct page **page_array)
+{
+       gfp_t preferred_gfp;
+       unsigned long nr_allocated = 0;
+
+       preferred_gfp = gfp | __GFP_NOWARN;
+       preferred_gfp &= ~(__GFP_DIRECT_RECLAIM | __GFP_NOFAIL);
+
+       nr_allocated  = __alloc_pages_bulk(preferred_gfp, nid, &pol->nodes,
+                                          nr_pages, NULL, page_array);
+
+       if (nr_allocated < nr_pages)
+               nr_allocated += __alloc_pages_bulk(gfp, numa_node_id(), NULL,
+                               nr_pages - nr_allocated, NULL,
+                               page_array + nr_allocated);
+       return nr_allocated;
+}
+
+/* alloc pages bulk and mempolicy should be considered at the
+ * same time in some situation such as vmalloc.
+ *
+ * It can accelerate memory allocation especially interleaving
+ * allocate memory.
+ */
+unsigned long alloc_pages_bulk_array_mempolicy(gfp_t gfp,
+               unsigned long nr_pages, struct page **page_array)
+{
+       struct mempolicy *pol = &default_policy;
+
+       if (!in_interrupt() && !(gfp & __GFP_THISNODE))
+               pol = get_task_policy(current);
+
+       if (pol->mode == MPOL_INTERLEAVE)
+               return alloc_pages_bulk_array_interleave(gfp, pol,
+                                                        nr_pages, page_array);
+
+       if (pol->mode == MPOL_PREFERRED_MANY)
+               return alloc_pages_bulk_array_preferred_many(gfp,
+                               numa_node_id(), pol, nr_pages, page_array);
+
+       return __alloc_pages_bulk(gfp, policy_node(gfp, pol, numa_node_id()),
+                                 policy_nodemask(gfp, pol), nr_pages, NULL,
+                                 page_array);
+}
+
 int vma_dup_policy(struct vm_area_struct *src, struct vm_area_struct *dst)
 {
        struct mempolicy *pol = mpol_dup(vma_policy(src));
@@ -2985,64 +3067,3 @@ void mpol_to_str(char *buffer, int maxlen, struct mempolicy *pol)
                p += scnprintf(p, buffer + maxlen - p, ":%*pbl",
                               nodemask_pr_args(&nodes));
 }
-
-bool numa_demotion_enabled = false;
-
-#ifdef CONFIG_SYSFS
-static ssize_t numa_demotion_enabled_show(struct kobject *kobj,
-                                         struct kobj_attribute *attr, char *buf)
-{
-       return sysfs_emit(buf, "%s\n",
-                         numa_demotion_enabled? "true" : "false");
-}
-
-static ssize_t numa_demotion_enabled_store(struct kobject *kobj,
-                                          struct kobj_attribute *attr,
-                                          const char *buf, size_t count)
-{
-       if (!strncmp(buf, "true", 4) || !strncmp(buf, "1", 1))
-               numa_demotion_enabled = true;
-       else if (!strncmp(buf, "false", 5) || !strncmp(buf, "0", 1))
-               numa_demotion_enabled = false;
-       else
-               return -EINVAL;
-
-       return count;
-}
-
-static struct kobj_attribute numa_demotion_enabled_attr =
-       __ATTR(demotion_enabled, 0644, numa_demotion_enabled_show,
-              numa_demotion_enabled_store);
-
-static struct attribute *numa_attrs[] = {
-       &numa_demotion_enabled_attr.attr,
-       NULL,
-};
-
-static const struct attribute_group numa_attr_group = {
-       .attrs = numa_attrs,
-};
-
-static int __init numa_init_sysfs(void)
-{
-       int err;
-       struct kobject *numa_kobj;
-
-       numa_kobj = kobject_create_and_add("numa", mm_kobj);
-       if (!numa_kobj) {
-               pr_err("failed to create numa kobject\n");
-               return -ENOMEM;
-       }
-       err = sysfs_create_group(numa_kobj, &numa_attr_group);
-       if (err) {
-               pr_err("failed to register numa group\n");
-               goto delete_obj;
-       }
-       return 0;
-
-delete_obj:
-       kobject_put(numa_kobj);
-       return err;
-}
-subsys_initcall(numa_init_sysfs);
-#endif