* [PATCH v2 08/18] zsmalloc: squeeze freelist into page->mapping
From: Minchan Kim @ 2016-03-21 6:30 UTC (permalink / raw)
To: Andrew Morton
Cc: Rik van Riel, YiPing Xu, aquini, rknize, Sergey Senozhatsky,
Chan Gyun Jeong, Minchan Kim, Hugh Dickins, linux-kernel, Al Viro,
virtualization, bfields, linux-mm, Gioh Kim, koct9i, Sangseok Lee,
jlayton, Joonsoo Kim, Vlastimil Babka, Mel Gorman
In-Reply-To: <1458541867-27380-1-git-send-email-minchan@kernel.org>
Zsmalloc stores first free object's position into first_page->freelist
in each zspage. If we change it with object index from first_page
instead of location, we could squeeze it into page->mapping because
the number of bit we need to store offset is at most 11bit.
Signed-off-by: Minchan Kim <minchan@kernel.org>
---
mm/zsmalloc.c | 159 +++++++++++++++++++++++++++++++++++-----------------------
1 file changed, 96 insertions(+), 63 deletions(-)
diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c
index 4dd72a803568..0c8ccd87c084 100644
--- a/mm/zsmalloc.c
+++ b/mm/zsmalloc.c
@@ -18,9 +18,7 @@
* Usage of struct page fields:
* page->private: points to the first component (0-order) page
* page->index (union with page->freelist): offset of the first object
- * starting in this page. For the first page, this is
- * always 0, so we use this field (aka freelist) to point
- * to the first free object in zspage.
+ * starting in this page.
* page->lru: links together all component pages (except the first page)
* of a zspage
*
@@ -29,9 +27,6 @@
* page->private: refers to the component page after the first page
* If the page is first_page for huge object, it stores handle.
* Look at size_class->huge.
- * page->freelist: points to the first free object in zspage.
- * Free objects are linked together using in-place
- * metadata.
* page->lru: links together first pages of various zspages.
* Basically forming list of zspages in a fullness group.
* page->mapping: override by struct zs_meta
@@ -131,6 +126,7 @@
/* each chunk includes extra space to keep handle */
#define ZS_MAX_ALLOC_SIZE PAGE_SIZE
+#define FREEOBJ_BITS 11
#define CLASS_BITS 8
#define CLASS_MASK ((1 << CLASS_BITS) - 1)
#define FULLNESS_BITS 2
@@ -228,17 +224,17 @@ struct size_class {
/*
* Placed within free objects to form a singly linked list.
- * For every zspage, first_page->freelist gives head of this list.
+ * For every zspage, first_page->freeobj gives head of this list.
*
* This must be power of 2 and less than or equal to ZS_ALIGN
*/
struct link_free {
union {
/*
- * Position of next free chunk (encodes <PFN, obj_idx>)
+ * free object list
* It's valid for non-allocated object
*/
- void *next;
+ unsigned long next;
/*
* Handle of allocated object.
*/
@@ -270,6 +266,7 @@ struct zs_pool {
};
struct zs_meta {
+ unsigned long freeobj:FREEOBJ_BITS;
unsigned long class:CLASS_BITS;
unsigned long fullness:FULLNESS_BITS;
unsigned long inuse:INUSE_BITS;
@@ -446,6 +443,26 @@ static void mod_zspage_inuse(struct page *first_page, int val)
m->inuse += val;
}
+static void set_freeobj(struct page *first_page, int idx)
+{
+ struct zs_meta *m;
+
+ VM_BUG_ON_PAGE(!is_first_page(first_page), first_page);
+
+ m = (struct zs_meta *)&first_page->mapping;
+ m->freeobj = idx;
+}
+
+static unsigned long get_freeobj(struct page *first_page)
+{
+ struct zs_meta *m;
+
+ VM_BUG_ON_PAGE(!is_first_page(first_page), first_page);
+
+ m = (struct zs_meta *)&first_page->mapping;
+ return m->freeobj;
+}
+
static void get_zspage_mapping(struct page *first_page,
unsigned int *class_idx,
enum fullness_group *fullness)
@@ -837,30 +854,33 @@ static struct page *get_next_page(struct page *page)
return next;
}
-/*
- * Encode <page, obj_idx> as a single handle value.
- * We use the least bit of handle for tagging.
- */
-static void *location_to_obj(struct page *page, unsigned long obj_idx)
+static void objidx_to_page_and_offset(struct size_class *class,
+ struct page *first_page,
+ unsigned long obj_idx,
+ struct page **obj_page,
+ unsigned long *offset_in_page)
{
- unsigned long obj;
+ int i;
+ unsigned long offset;
+ struct page *cursor;
+ int nr_page;
- if (!page) {
- VM_BUG_ON(obj_idx);
- return NULL;
- }
+ offset = obj_idx * class->size;
+ cursor = first_page;
+ nr_page = offset >> PAGE_SHIFT;
- obj = page_to_pfn(page) << OBJ_INDEX_BITS;
- obj |= ((obj_idx) & OBJ_INDEX_MASK);
- obj <<= OBJ_TAG_BITS;
+ *offset_in_page = offset & ~PAGE_MASK;
+
+ for (i = 0; i < nr_page; i++)
+ cursor = get_next_page(cursor);
- return (void *)obj;
+ *obj_page = cursor;
}
-/*
- * Decode <page, obj_idx> pair from the given object handle. We adjust the
- * decoded obj_idx back to its original value since it was adjusted in
- * location_to_obj().
+/**
+ * obj_to_location - get (<page>, <obj_idx>) from encoded object value
+ * @page: page object resides in zspage
+ * @obj_idx: object index
*/
static void obj_to_location(unsigned long obj, struct page **page,
unsigned long *obj_idx)
@@ -870,6 +890,23 @@ static void obj_to_location(unsigned long obj, struct page **page,
*obj_idx = (obj & OBJ_INDEX_MASK);
}
+/**
+ * location_to_obj - get obj value encoded from (<page>, <obj_idx>)
+ * @page: page object resides in zspage
+ * @obj_idx: object index
+ */
+static unsigned long location_to_obj(struct page *page,
+ unsigned long obj_idx)
+{
+ unsigned long obj;
+
+ obj = page_to_pfn(page) << OBJ_INDEX_BITS;
+ obj |= obj_idx & OBJ_INDEX_MASK;
+ obj <<= OBJ_TAG_BITS;
+
+ return obj;
+}
+
static unsigned long handle_to_obj(unsigned long handle)
{
return *(unsigned long *)handle;
@@ -885,17 +922,6 @@ static unsigned long obj_to_head(struct size_class *class, struct page *page,
return *(unsigned long *)obj;
}
-static unsigned long obj_idx_to_offset(struct page *page,
- unsigned long obj_idx, int class_size)
-{
- unsigned long off = 0;
-
- if (!is_first_page(page))
- off = page->index;
-
- return off + obj_idx * class_size;
-}
-
static inline int trypin_tag(unsigned long handle)
{
unsigned long *ptr = (unsigned long *)handle;
@@ -921,7 +947,6 @@ static void reset_page(struct page *page)
clear_bit(PG_private_2, &page->flags);
set_page_private(page, 0);
page->mapping = NULL;
- page->freelist = NULL;
page_mapcount_reset(page);
}
@@ -953,6 +978,7 @@ static void free_zspage(struct page *first_page)
/* Initialize a newly allocated zspage */
static void init_zspage(struct size_class *class, struct page *first_page)
{
+ int freeobj = 1;
unsigned long off = 0;
struct page *page = first_page;
@@ -961,14 +987,11 @@ static void init_zspage(struct size_class *class, struct page *first_page)
while (page) {
struct page *next_page;
struct link_free *link;
- unsigned int i = 1;
void *vaddr;
/*
* page->index stores offset of first object starting
- * in the page. For the first page, this is always 0,
- * so we use first_page->index (aka ->freelist) to store
- * head of corresponding zspage's freelist.
+ * in the page.
*/
if (page != first_page)
page->index = off;
@@ -977,7 +1000,7 @@ static void init_zspage(struct size_class *class, struct page *first_page)
link = (struct link_free *)vaddr + off / sizeof(*link);
while ((off += class->size) < PAGE_SIZE) {
- link->next = location_to_obj(page, i++);
+ link->next = freeobj++ << OBJ_ALLOCATED_TAG;
link += class->size / sizeof(*link);
}
@@ -987,11 +1010,21 @@ static void init_zspage(struct size_class *class, struct page *first_page)
* page (if present)
*/
next_page = get_next_page(page);
- link->next = location_to_obj(next_page, 0);
+ if (next_page) {
+ link->next = freeobj++ << OBJ_ALLOCATED_TAG;
+ } else {
+ /*
+ * Reset OBJ_ALLOCATED_TAG bit to last link for
+ * migration to know it is allocated object or not.
+ */
+ link->next = -1 << OBJ_ALLOCATED_TAG;
+ }
kunmap_atomic(vaddr);
page = next_page;
off %= PAGE_SIZE;
}
+
+ set_freeobj(first_page, 0);
}
/*
@@ -1041,7 +1074,6 @@ static struct page *alloc_zspage(struct size_class *class, gfp_t flags)
init_zspage(class, first_page);
- first_page->freelist = location_to_obj(first_page, 0);
error = 0; /* Success */
cleanup:
@@ -1321,7 +1353,7 @@ void *zs_map_object(struct zs_pool *pool, unsigned long handle,
obj_to_location(obj, &page, &obj_idx);
get_zspage_mapping(get_first_page(page), &class_idx, &fg);
class = pool->size_class[class_idx];
- off = obj_idx_to_offset(page, obj_idx, class->size);
+ off = (class->size * obj_idx) & ~PAGE_MASK;
area = &get_cpu_var(zs_map_area);
area->vm_mm = mm;
@@ -1360,7 +1392,7 @@ void zs_unmap_object(struct zs_pool *pool, unsigned long handle)
obj_to_location(obj, &page, &obj_idx);
get_zspage_mapping(get_first_page(page), &class_idx, &fg);
class = pool->size_class[class_idx];
- off = obj_idx_to_offset(page, obj_idx, class->size);
+ off = (class->size * obj_idx) & ~PAGE_MASK;
area = this_cpu_ptr(&zs_map_area);
if (off + class->size <= PAGE_SIZE)
@@ -1386,17 +1418,17 @@ static unsigned long obj_malloc(struct size_class *class,
struct link_free *link;
struct page *m_page;
- unsigned long m_objidx, m_offset;
+ unsigned long m_offset;
void *vaddr;
handle |= OBJ_ALLOCATED_TAG;
- obj = (unsigned long)first_page->freelist;
- obj_to_location(obj, &m_page, &m_objidx);
- m_offset = obj_idx_to_offset(m_page, m_objidx, class->size);
+ obj = get_freeobj(first_page);
+ objidx_to_page_and_offset(class, first_page, obj,
+ &m_page, &m_offset);
vaddr = kmap_atomic(m_page);
link = (struct link_free *)vaddr + m_offset / sizeof(*link);
- first_page->freelist = link->next;
+ set_freeobj(first_page, link->next >> OBJ_ALLOCATED_TAG);
if (!class->huge)
/* record handle in the header of allocated chunk */
link->handle = handle;
@@ -1407,6 +1439,8 @@ static unsigned long obj_malloc(struct size_class *class,
mod_zspage_inuse(first_page, 1);
zs_stat_inc(class, OBJ_USED, 1);
+ obj = location_to_obj(m_page, obj);
+
return obj;
}
@@ -1476,19 +1510,17 @@ static void obj_free(struct size_class *class, unsigned long obj)
obj &= ~OBJ_ALLOCATED_TAG;
obj_to_location(obj, &f_page, &f_objidx);
+ f_offset = (class->size * f_objidx) & ~PAGE_MASK;
first_page = get_first_page(f_page);
-
- f_offset = obj_idx_to_offset(f_page, f_objidx, class->size);
-
vaddr = kmap_atomic(f_page);
/* Insert this object in containing zspage's freelist */
link = (struct link_free *)(vaddr + f_offset);
- link->next = first_page->freelist;
+ link->next = get_freeobj(first_page) << OBJ_ALLOCATED_TAG;
if (class->huge)
set_page_private(first_page, 0);
kunmap_atomic(vaddr);
- first_page->freelist = (void *)obj;
+ set_freeobj(first_page, f_objidx);
mod_zspage_inuse(first_page, -1);
zs_stat_dec(class, OBJ_USED, 1);
}
@@ -1544,8 +1576,8 @@ static void zs_object_copy(struct size_class *class, unsigned long dst,
obj_to_location(src, &s_page, &s_objidx);
obj_to_location(dst, &d_page, &d_objidx);
- s_off = obj_idx_to_offset(s_page, s_objidx, class->size);
- d_off = obj_idx_to_offset(d_page, d_objidx, class->size);
+ s_off = (class->size * s_objidx) & ~PAGE_MASK;
+ d_off = (class->size * d_objidx) & ~PAGE_MASK;
if (s_off + class->size > PAGE_SIZE)
s_size = PAGE_SIZE - s_off;
@@ -2035,9 +2067,10 @@ static int __init zs_init(void)
goto notifier_fail;
/*
- * A zspage's class index, fullness group, inuse object count are
- * encoded in its (first)page->mapping so sizeof(struct zs_meta)
- * should be less than sizeof(page->mapping(i.e., unsigned long)).
+ * A zspage's a free object index, class index, fullness group,
+ * inuse object count are encoded in its (first)page->mapping
+ * so sizeof(struct zs_meta) should be less than
+ * sizeof(page->mapping(i.e., unsigned long)).
*/
BUILD_BUG_ON(sizeof(struct zs_meta) > sizeof(unsigned long));
--
1.9.1
^ permalink raw reply related
* [PATCH v2 07/18] zsmalloc: squeeze inuse into page->mapping
From: Minchan Kim @ 2016-03-21 6:30 UTC (permalink / raw)
To: Andrew Morton
Cc: Rik van Riel, YiPing Xu, aquini, rknize, Sergey Senozhatsky,
Chan Gyun Jeong, Minchan Kim, Hugh Dickins, linux-kernel, Al Viro,
virtualization, bfields, linux-mm, Gioh Kim, koct9i, Sangseok Lee,
jlayton, Joonsoo Kim, Vlastimil Babka, Mel Gorman
In-Reply-To: <1458541867-27380-1-git-send-email-minchan@kernel.org>
Currently, we store class:fullness into page->mapping.
The number of class we can support is 255 and fullness is 4 so
(8 + 2 = 10bit) is enough to represent them.
Meanwhile, the bits we need to store in-use objects in zspage
is that 11bit is enough.
For example, If we assume that 64K PAGE_SIZE, class_size 32
which is worst case, class->pages_per_zspage become 1 so
the number of objects in zspage is 2048 so 11bit is enough.
The next class is 32 + 256(i.e., ZS_SIZE_CLASS_DELTA).
With worst case that ZS_MAX_PAGES_PER_ZSPAGE, 64K * 4 /
(32 + 256) = 910 so 11bit is still enough.
So, we could squeeze inuse object count to page->mapping.
Signed-off-by: Minchan Kim <minchan@kernel.org>
---
mm/zsmalloc.c | 103 ++++++++++++++++++++++++++++++++++++++++------------------
1 file changed, 71 insertions(+), 32 deletions(-)
diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c
index 8649d0243e6c..4dd72a803568 100644
--- a/mm/zsmalloc.c
+++ b/mm/zsmalloc.c
@@ -34,8 +34,7 @@
* metadata.
* page->lru: links together first pages of various zspages.
* Basically forming list of zspages in a fullness group.
- * page->mapping: class index and fullness group of the zspage
- * page->inuse: the number of objects that are used in this zspage
+ * page->mapping: override by struct zs_meta
*
* Usage of struct page flags:
* PG_private: identifies the first component page
@@ -132,6 +131,13 @@
/* each chunk includes extra space to keep handle */
#define ZS_MAX_ALLOC_SIZE PAGE_SIZE
+#define CLASS_BITS 8
+#define CLASS_MASK ((1 << CLASS_BITS) - 1)
+#define FULLNESS_BITS 2
+#define FULLNESS_MASK ((1 << FULLNESS_BITS) - 1)
+#define INUSE_BITS 11
+#define INUSE_MASK ((1 << INUSE_BITS) - 1)
+
/*
* On systems with 4K page size, this gives 255 size classes! There is a
* trader-off here:
@@ -145,7 +151,7 @@
* ZS_MIN_ALLOC_SIZE and ZS_SIZE_CLASS_DELTA must be multiple of ZS_ALIGN
* (reason above)
*/
-#define ZS_SIZE_CLASS_DELTA (PAGE_SIZE >> 8)
+#define ZS_SIZE_CLASS_DELTA (PAGE_SIZE >> CLASS_BITS)
/*
* We do not maintain any list for completely empty or full pages
@@ -155,7 +161,7 @@ enum fullness_group {
ZS_ALMOST_EMPTY,
_ZS_NR_FULLNESS_GROUPS,
- ZS_EMPTY,
+ ZS_EMPTY = _ZS_NR_FULLNESS_GROUPS,
ZS_FULL
};
@@ -263,14 +269,11 @@ struct zs_pool {
#endif
};
-/*
- * A zspage's class index and fullness group
- * are encoded in its (first)page->mapping
- */
-#define CLASS_IDX_BITS 28
-#define FULLNESS_BITS 4
-#define CLASS_IDX_MASK ((1 << CLASS_IDX_BITS) - 1)
-#define FULLNESS_MASK ((1 << FULLNESS_BITS) - 1)
+struct zs_meta {
+ unsigned long class:CLASS_BITS;
+ unsigned long fullness:FULLNESS_BITS;
+ unsigned long inuse:INUSE_BITS;
+};
struct mapping_area {
#ifdef CONFIG_PGTABLE_MAPPING
@@ -412,28 +415,61 @@ static int is_last_page(struct page *page)
return PagePrivate2(page);
}
+static int get_zspage_inuse(struct page *first_page)
+{
+ struct zs_meta *m;
+
+ VM_BUG_ON_PAGE(!is_first_page(first_page), first_page);
+
+ m = (struct zs_meta *)&first_page->mapping;
+
+ return m->inuse;
+}
+
+static void set_zspage_inuse(struct page *first_page, int val)
+{
+ struct zs_meta *m;
+
+ VM_BUG_ON_PAGE(!is_first_page(first_page), first_page);
+
+ m = (struct zs_meta *)&first_page->mapping;
+ m->inuse = val;
+}
+
+static void mod_zspage_inuse(struct page *first_page, int val)
+{
+ struct zs_meta *m;
+
+ VM_BUG_ON_PAGE(!is_first_page(first_page), first_page);
+
+ m = (struct zs_meta *)&first_page->mapping;
+ m->inuse += val;
+}
+
static void get_zspage_mapping(struct page *first_page,
unsigned int *class_idx,
enum fullness_group *fullness)
{
- unsigned long m;
+ struct zs_meta *m;
+
VM_BUG_ON_PAGE(!is_first_page(first_page), first_page);
- m = (unsigned long)first_page->mapping;
- *fullness = m & FULLNESS_MASK;
- *class_idx = (m >> FULLNESS_BITS) & CLASS_IDX_MASK;
+ m = (struct zs_meta *)&first_page->mapping;
+ *fullness = m->fullness;
+ *class_idx = m->class;
}
static void set_zspage_mapping(struct page *first_page,
unsigned int class_idx,
enum fullness_group fullness)
{
- unsigned long m;
+ struct zs_meta *m;
+
VM_BUG_ON_PAGE(!is_first_page(first_page), first_page);
- m = ((class_idx & CLASS_IDX_MASK) << FULLNESS_BITS) |
- (fullness & FULLNESS_MASK);
- first_page->mapping = (struct address_space *)m;
+ m = (struct zs_meta *)&first_page->mapping;
+ m->fullness = fullness;
+ m->class = class_idx;
}
/*
@@ -632,9 +668,7 @@ static enum fullness_group get_fullness_group(struct size_class *class,
int inuse, objs_per_zspage;
enum fullness_group fg;
- VM_BUG_ON_PAGE(!is_first_page(first_page), first_page);
-
- inuse = first_page->inuse;
+ inuse = get_zspage_inuse(first_page);
objs_per_zspage = class->objs_per_zspage;
if (inuse == 0)
@@ -677,10 +711,10 @@ static void insert_zspage(struct size_class *class,
/*
* We want to see more ZS_FULL pages and less almost
- * empty/full. Put pages with higher ->inuse first.
+ * empty/full. Put pages with higher inuse first.
*/
list_add_tail(&first_page->lru, &(*head)->lru);
- if (first_page->inuse >= (*head)->inuse)
+ if (get_zspage_inuse(first_page) >= get_zspage_inuse(*head))
*head = first_page;
}
@@ -896,7 +930,7 @@ static void free_zspage(struct page *first_page)
struct page *nextp, *tmp, *head_extra;
VM_BUG_ON_PAGE(!is_first_page(first_page), first_page);
- VM_BUG_ON_PAGE(first_page->inuse, first_page);
+ VM_BUG_ON_PAGE(get_zspage_inuse(first_page), first_page);
head_extra = (struct page *)page_private(first_page);
@@ -992,7 +1026,7 @@ static struct page *alloc_zspage(struct size_class *class, gfp_t flags)
SetPagePrivate(page);
set_page_private(page, 0);
first_page = page;
- first_page->inuse = 0;
+ set_zspage_inuse(page, 0);
}
if (i == 1)
set_page_private(first_page, (unsigned long)page);
@@ -1237,9 +1271,7 @@ static bool can_merge(struct size_class *prev, int size, int pages_per_zspage)
static bool zspage_full(struct size_class *class, struct page *first_page)
{
- VM_BUG_ON_PAGE(!is_first_page(first_page), first_page);
-
- return first_page->inuse == class->objs_per_zspage;
+ return get_zspage_inuse(first_page) == class->objs_per_zspage;
}
unsigned long zs_get_total_pages(struct zs_pool *pool)
@@ -1372,7 +1404,7 @@ static unsigned long obj_malloc(struct size_class *class,
/* record handle in first_page->private */
set_page_private(first_page, handle);
kunmap_atomic(vaddr);
- first_page->inuse++;
+ mod_zspage_inuse(first_page, 1);
zs_stat_inc(class, OBJ_USED, 1);
return obj;
@@ -1457,7 +1489,7 @@ static void obj_free(struct size_class *class, unsigned long obj)
set_page_private(first_page, 0);
kunmap_atomic(vaddr);
first_page->freelist = (void *)obj;
- first_page->inuse--;
+ mod_zspage_inuse(first_page, -1);
zs_stat_dec(class, OBJ_USED, 1);
}
@@ -2002,6 +2034,13 @@ static int __init zs_init(void)
if (ret)
goto notifier_fail;
+ /*
+ * A zspage's class index, fullness group, inuse object count are
+ * encoded in its (first)page->mapping so sizeof(struct zs_meta)
+ * should be less than sizeof(page->mapping(i.e., unsigned long)).
+ */
+ BUILD_BUG_ON(sizeof(struct zs_meta) > sizeof(unsigned long));
+
init_zs_size_classes();
#ifdef CONFIG_ZPOOL
--
1.9.1
^ permalink raw reply related
* [PATCH v2 06/18] zsmalloc: keep max_object in size_class
From: Minchan Kim @ 2016-03-21 6:30 UTC (permalink / raw)
To: Andrew Morton
Cc: Rik van Riel, YiPing Xu, aquini, rknize, Sergey Senozhatsky,
Chan Gyun Jeong, Minchan Kim, Hugh Dickins, linux-kernel, Al Viro,
virtualization, bfields, linux-mm, Gioh Kim, koct9i, Sangseok Lee,
jlayton, Joonsoo Kim, Vlastimil Babka, Mel Gorman
In-Reply-To: <1458541867-27380-1-git-send-email-minchan@kernel.org>
Every zspage in a size_class has same number of max objects so
we could move it to a size_class.
Signed-off-by: Minchan Kim <minchan@kernel.org>
---
mm/zsmalloc.c | 32 +++++++++++++++-----------------
1 file changed, 15 insertions(+), 17 deletions(-)
diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c
index a0890e9003e2..8649d0243e6c 100644
--- a/mm/zsmalloc.c
+++ b/mm/zsmalloc.c
@@ -32,8 +32,6 @@
* page->freelist: points to the first free object in zspage.
* Free objects are linked together using in-place
* metadata.
- * page->objects: maximum number of objects we can store in this
- * zspage (class->zspage_order * PAGE_SIZE / class->size)
* page->lru: links together first pages of various zspages.
* Basically forming list of zspages in a fullness group.
* page->mapping: class index and fullness group of the zspage
@@ -211,6 +209,7 @@ struct size_class {
* of ZS_ALIGN.
*/
int size;
+ int objs_per_zspage;
unsigned int index;
struct zs_size_stat stats;
@@ -627,21 +626,22 @@ static inline void zs_pool_stat_destroy(struct zs_pool *pool)
* the pool (not yet implemented). This function returns fullness
* status of the given page.
*/
-static enum fullness_group get_fullness_group(struct page *first_page)
+static enum fullness_group get_fullness_group(struct size_class *class,
+ struct page *first_page)
{
- int inuse, max_objects;
+ int inuse, objs_per_zspage;
enum fullness_group fg;
VM_BUG_ON_PAGE(!is_first_page(first_page), first_page);
inuse = first_page->inuse;
- max_objects = first_page->objects;
+ objs_per_zspage = class->objs_per_zspage;
if (inuse == 0)
fg = ZS_EMPTY;
- else if (inuse == max_objects)
+ else if (inuse == objs_per_zspage)
fg = ZS_FULL;
- else if (inuse <= 3 * max_objects / fullness_threshold_frac)
+ else if (inuse <= 3 * objs_per_zspage / fullness_threshold_frac)
fg = ZS_ALMOST_EMPTY;
else
fg = ZS_ALMOST_FULL;
@@ -728,7 +728,7 @@ static enum fullness_group fix_fullness_group(struct size_class *class,
enum fullness_group currfg, newfg;
get_zspage_mapping(first_page, &class_idx, &currfg);
- newfg = get_fullness_group(first_page);
+ newfg = get_fullness_group(class, first_page);
if (newfg == currfg)
goto out;
@@ -1008,9 +1008,6 @@ static struct page *alloc_zspage(struct size_class *class, gfp_t flags)
init_zspage(class, first_page);
first_page->freelist = location_to_obj(first_page, 0);
- /* Maximum number of objects we can store in this zspage */
- first_page->objects = class->pages_per_zspage * PAGE_SIZE / class->size;
-
error = 0; /* Success */
cleanup:
@@ -1238,11 +1235,11 @@ static bool can_merge(struct size_class *prev, int size, int pages_per_zspage)
return true;
}
-static bool zspage_full(struct page *first_page)
+static bool zspage_full(struct size_class *class, struct page *first_page)
{
VM_BUG_ON_PAGE(!is_first_page(first_page), first_page);
- return first_page->inuse == first_page->objects;
+ return first_page->inuse == class->objs_per_zspage;
}
unsigned long zs_get_total_pages(struct zs_pool *pool)
@@ -1628,7 +1625,7 @@ static int migrate_zspage(struct zs_pool *pool, struct size_class *class,
}
/* Stop if there is no more space */
- if (zspage_full(d_page)) {
+ if (zspage_full(class, d_page)) {
unpin_tag(handle);
ret = -ENOMEM;
break;
@@ -1687,7 +1684,7 @@ static enum fullness_group putback_zspage(struct zs_pool *pool,
{
enum fullness_group fullness;
- fullness = get_fullness_group(first_page);
+ fullness = get_fullness_group(class, first_page);
insert_zspage(class, fullness, first_page);
set_zspage_mapping(first_page, class->index, fullness);
@@ -1936,8 +1933,9 @@ struct zs_pool *zs_create_pool(const char *name, gfp_t flags)
class->size = size;
class->index = i;
class->pages_per_zspage = pages_per_zspage;
- if (pages_per_zspage == 1 &&
- get_maxobj_per_zspage(size, pages_per_zspage) == 1)
+ class->objs_per_zspage = class->pages_per_zspage *
+ PAGE_SIZE / class->size;
+ if (pages_per_zspage == 1 && class->objs_per_zspage == 1)
class->huge = true;
spin_lock_init(&class->lock);
pool->size_class[i] = class;
--
1.9.1
^ permalink raw reply related
* [PATCH v2 05/18] zsmalloc: remove unused pool param in obj_free
From: Minchan Kim @ 2016-03-21 6:30 UTC (permalink / raw)
To: Andrew Morton
Cc: Rik van Riel, YiPing Xu, aquini, rknize, Sergey Senozhatsky,
Chan Gyun Jeong, Minchan Kim, Hugh Dickins, linux-kernel, Al Viro,
virtualization, bfields, linux-mm, Gioh Kim, koct9i, Sangseok Lee,
jlayton, Joonsoo Kim, Vlastimil Babka, Mel Gorman
In-Reply-To: <1458541867-27380-1-git-send-email-minchan@kernel.org>
Let's remove unused pool param in obj_free
Reviewed-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
Signed-off-by: Minchan Kim <minchan@kernel.org>
---
mm/zsmalloc.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c
index 16556a6db628..a0890e9003e2 100644
--- a/mm/zsmalloc.c
+++ b/mm/zsmalloc.c
@@ -1438,8 +1438,7 @@ unsigned long zs_malloc(struct zs_pool *pool, size_t size)
}
EXPORT_SYMBOL_GPL(zs_malloc);
-static void obj_free(struct zs_pool *pool, struct size_class *class,
- unsigned long obj)
+static void obj_free(struct size_class *class, unsigned long obj)
{
struct link_free *link;
struct page *first_page, *f_page;
@@ -1485,7 +1484,7 @@ void zs_free(struct zs_pool *pool, unsigned long handle)
class = pool->size_class[class_idx];
spin_lock(&class->lock);
- obj_free(pool, class, obj);
+ obj_free(class, obj);
fullness = fix_fullness_group(class, first_page);
if (fullness == ZS_EMPTY) {
zs_stat_dec(class, OBJ_ALLOCATED, get_maxobj_per_zspage(
@@ -1648,7 +1647,7 @@ static int migrate_zspage(struct zs_pool *pool, struct size_class *class,
free_obj |= BIT(HANDLE_PIN_BIT);
record_obj(handle, free_obj);
unpin_tag(handle);
- obj_free(pool, class, used_obj);
+ obj_free(class, used_obj);
}
/* Remember last position in this iteration */
--
1.9.1
^ permalink raw reply related
* [PATCH v2 04/18] zsmalloc: reordering function parameter
From: Minchan Kim @ 2016-03-21 6:30 UTC (permalink / raw)
To: Andrew Morton
Cc: Rik van Riel, YiPing Xu, aquini, rknize, Sergey Senozhatsky,
Chan Gyun Jeong, Minchan Kim, Hugh Dickins, linux-kernel, Al Viro,
virtualization, bfields, linux-mm, Gioh Kim, koct9i, Sangseok Lee,
jlayton, Joonsoo Kim, Vlastimil Babka, Mel Gorman
In-Reply-To: <1458541867-27380-1-git-send-email-minchan@kernel.org>
This patch cleans up function parameter ordering to order
higher data structure first.
Reviewed-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
Signed-off-by: Minchan Kim <minchan@kernel.org>
---
mm/zsmalloc.c | 50 ++++++++++++++++++++++++++------------------------
1 file changed, 26 insertions(+), 24 deletions(-)
diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c
index 6a7b9313ee8c..16556a6db628 100644
--- a/mm/zsmalloc.c
+++ b/mm/zsmalloc.c
@@ -569,7 +569,7 @@ static const struct file_operations zs_stat_size_ops = {
.release = single_release,
};
-static int zs_pool_stat_create(const char *name, struct zs_pool *pool)
+static int zs_pool_stat_create(struct zs_pool *pool, const char *name)
{
struct dentry *entry;
@@ -609,7 +609,7 @@ static void __exit zs_stat_exit(void)
{
}
-static inline int zs_pool_stat_create(const char *name, struct zs_pool *pool)
+static inline int zs_pool_stat_create(struct zs_pool *pool, const char *name)
{
return 0;
}
@@ -655,8 +655,9 @@ static enum fullness_group get_fullness_group(struct page *first_page)
* have. This functions inserts the given zspage into the freelist
* identified by <class, fullness_group>.
*/
-static void insert_zspage(struct page *first_page, struct size_class *class,
- enum fullness_group fullness)
+static void insert_zspage(struct size_class *class,
+ enum fullness_group fullness,
+ struct page *first_page)
{
struct page **head;
@@ -687,8 +688,9 @@ static void insert_zspage(struct page *first_page, struct size_class *class,
* This function removes the given zspage from the freelist identified
* by <class, fullness_group>.
*/
-static void remove_zspage(struct page *first_page, struct size_class *class,
- enum fullness_group fullness)
+static void remove_zspage(struct size_class *class,
+ enum fullness_group fullness,
+ struct page *first_page)
{
struct page **head;
@@ -730,8 +732,8 @@ static enum fullness_group fix_fullness_group(struct size_class *class,
if (newfg == currfg)
goto out;
- remove_zspage(first_page, class, currfg);
- insert_zspage(first_page, class, newfg);
+ remove_zspage(class, currfg, first_page);
+ insert_zspage(class, newfg, first_page);
set_zspage_mapping(first_page, class_idx, newfg);
out:
@@ -915,7 +917,7 @@ static void free_zspage(struct page *first_page)
}
/* Initialize a newly allocated zspage */
-static void init_zspage(struct page *first_page, struct size_class *class)
+static void init_zspage(struct size_class *class, struct page *first_page)
{
unsigned long off = 0;
struct page *page = first_page;
@@ -1003,7 +1005,7 @@ static struct page *alloc_zspage(struct size_class *class, gfp_t flags)
prev_page = page;
}
- init_zspage(first_page, class);
+ init_zspage(class, first_page);
first_page->freelist = location_to_obj(first_page, 0);
/* Maximum number of objects we can store in this zspage */
@@ -1348,8 +1350,8 @@ void zs_unmap_object(struct zs_pool *pool, unsigned long handle)
}
EXPORT_SYMBOL_GPL(zs_unmap_object);
-static unsigned long obj_malloc(struct page *first_page,
- struct size_class *class, unsigned long handle)
+static unsigned long obj_malloc(struct size_class *class,
+ struct page *first_page, unsigned long handle)
{
unsigned long obj;
struct link_free *link;
@@ -1426,7 +1428,7 @@ unsigned long zs_malloc(struct zs_pool *pool, size_t size)
class->size, class->pages_per_zspage));
}
- obj = obj_malloc(first_page, class, handle);
+ obj = obj_malloc(class, first_page, handle);
/* Now move the zspage to another fullness group, if required */
fix_fullness_group(class, first_page);
record_obj(handle, obj);
@@ -1499,8 +1501,8 @@ void zs_free(struct zs_pool *pool, unsigned long handle)
}
EXPORT_SYMBOL_GPL(zs_free);
-static void zs_object_copy(unsigned long dst, unsigned long src,
- struct size_class *class)
+static void zs_object_copy(struct size_class *class, unsigned long dst,
+ unsigned long src)
{
struct page *s_page, *d_page;
unsigned long s_objidx, d_objidx;
@@ -1566,8 +1568,8 @@ static void zs_object_copy(unsigned long dst, unsigned long src,
* Find alloced object in zspage from index object and
* return handle.
*/
-static unsigned long find_alloced_obj(struct page *page, int index,
- struct size_class *class)
+static unsigned long find_alloced_obj(struct size_class *class,
+ struct page *page, int index)
{
unsigned long head;
int offset = 0;
@@ -1617,7 +1619,7 @@ static int migrate_zspage(struct zs_pool *pool, struct size_class *class,
int ret = 0;
while (1) {
- handle = find_alloced_obj(s_page, index, class);
+ handle = find_alloced_obj(class, s_page, index);
if (!handle) {
s_page = get_next_page(s_page);
if (!s_page)
@@ -1634,8 +1636,8 @@ static int migrate_zspage(struct zs_pool *pool, struct size_class *class,
}
used_obj = handle_to_obj(handle);
- free_obj = obj_malloc(d_page, class, handle);
- zs_object_copy(free_obj, used_obj, class);
+ free_obj = obj_malloc(class, d_page, handle);
+ zs_object_copy(class, free_obj, used_obj);
index++;
/*
* record_obj updates handle's value to free_obj and it will
@@ -1664,7 +1666,7 @@ static struct page *isolate_target_page(struct size_class *class)
for (i = 0; i < _ZS_NR_FULLNESS_GROUPS; i++) {
page = class->fullness_list[i];
if (page) {
- remove_zspage(page, class, i);
+ remove_zspage(class, i, page);
break;
}
}
@@ -1687,7 +1689,7 @@ static enum fullness_group putback_zspage(struct zs_pool *pool,
enum fullness_group fullness;
fullness = get_fullness_group(first_page);
- insert_zspage(first_page, class, fullness);
+ insert_zspage(class, fullness, first_page);
set_zspage_mapping(first_page, class->index, fullness);
if (fullness == ZS_EMPTY) {
@@ -1712,7 +1714,7 @@ static struct page *isolate_source_page(struct size_class *class)
if (!page)
continue;
- remove_zspage(page, class, i);
+ remove_zspage(class, i, page);
break;
}
@@ -1946,7 +1948,7 @@ struct zs_pool *zs_create_pool(const char *name, gfp_t flags)
pool->flags = flags;
- if (zs_pool_stat_create(name, pool))
+ if (zs_pool_stat_create(pool, name))
goto err;
/*
--
1.9.1
^ permalink raw reply related
* [PATCH v2 03/18] zsmalloc: clean up many BUG_ON
From: Minchan Kim @ 2016-03-21 6:30 UTC (permalink / raw)
To: Andrew Morton
Cc: Rik van Riel, YiPing Xu, aquini, rknize, Sergey Senozhatsky,
Chan Gyun Jeong, Minchan Kim, Hugh Dickins, linux-kernel, Al Viro,
virtualization, bfields, linux-mm, Gioh Kim, koct9i, Sangseok Lee,
jlayton, Joonsoo Kim, Vlastimil Babka, Mel Gorman
In-Reply-To: <1458541867-27380-1-git-send-email-minchan@kernel.org>
There are many BUG_ON in zsmalloc.c which is not recommened so
change them as alternatives.
Normal rule is as follows:
1. avoid BUG_ON if possible. Instead, use VM_BUG_ON or VM_BUG_ON_PAGE
2. use VM_BUG_ON_PAGE if we need to see struct page's fields
3. use those assertion in primitive functions so higher functions
can rely on the assertion in the primitive function.
4. Don't use assertion if following instruction can trigger Oops
Reviewed-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
Signed-off-by: Minchan Kim <minchan@kernel.org>
---
mm/zsmalloc.c | 42 +++++++++++++++---------------------------
1 file changed, 15 insertions(+), 27 deletions(-)
diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c
index b09a80d398c9..6a7b9313ee8c 100644
--- a/mm/zsmalloc.c
+++ b/mm/zsmalloc.c
@@ -418,7 +418,7 @@ static void get_zspage_mapping(struct page *first_page,
enum fullness_group *fullness)
{
unsigned long m;
- BUG_ON(!is_first_page(first_page));
+ VM_BUG_ON_PAGE(!is_first_page(first_page), first_page);
m = (unsigned long)first_page->mapping;
*fullness = m & FULLNESS_MASK;
@@ -430,7 +430,7 @@ static void set_zspage_mapping(struct page *first_page,
enum fullness_group fullness)
{
unsigned long m;
- BUG_ON(!is_first_page(first_page));
+ VM_BUG_ON_PAGE(!is_first_page(first_page), first_page);
m = ((class_idx & CLASS_IDX_MASK) << FULLNESS_BITS) |
(fullness & FULLNESS_MASK);
@@ -631,7 +631,8 @@ static enum fullness_group get_fullness_group(struct page *first_page)
{
int inuse, max_objects;
enum fullness_group fg;
- BUG_ON(!is_first_page(first_page));
+
+ VM_BUG_ON_PAGE(!is_first_page(first_page), first_page);
inuse = first_page->inuse;
max_objects = first_page->objects;
@@ -659,7 +660,7 @@ static void insert_zspage(struct page *first_page, struct size_class *class,
{
struct page **head;
- BUG_ON(!is_first_page(first_page));
+ VM_BUG_ON_PAGE(!is_first_page(first_page), first_page);
if (fullness >= _ZS_NR_FULLNESS_GROUPS)
return;
@@ -691,13 +692,13 @@ static void remove_zspage(struct page *first_page, struct size_class *class,
{
struct page **head;
- BUG_ON(!is_first_page(first_page));
+ VM_BUG_ON_PAGE(!is_first_page(first_page), first_page);
if (fullness >= _ZS_NR_FULLNESS_GROUPS)
return;
head = &class->fullness_list[fullness];
- BUG_ON(!*head);
+ VM_BUG_ON_PAGE(!*head, first_page);
if (list_empty(&(*head)->lru))
*head = NULL;
else if (*head == first_page)
@@ -724,8 +725,6 @@ static enum fullness_group fix_fullness_group(struct size_class *class,
int class_idx;
enum fullness_group currfg, newfg;
- BUG_ON(!is_first_page(first_page));
-
get_zspage_mapping(first_page, &class_idx, &currfg);
newfg = get_fullness_group(first_page);
if (newfg == currfg)
@@ -811,7 +810,7 @@ static void *location_to_obj(struct page *page, unsigned long obj_idx)
unsigned long obj;
if (!page) {
- BUG_ON(obj_idx);
+ VM_BUG_ON(obj_idx);
return NULL;
}
@@ -844,7 +843,7 @@ static unsigned long obj_to_head(struct size_class *class, struct page *page,
void *obj)
{
if (class->huge) {
- VM_BUG_ON(!is_first_page(page));
+ VM_BUG_ON_PAGE(!is_first_page(page), page);
return page_private(page);
} else
return *(unsigned long *)obj;
@@ -894,8 +893,8 @@ static void free_zspage(struct page *first_page)
{
struct page *nextp, *tmp, *head_extra;
- BUG_ON(!is_first_page(first_page));
- BUG_ON(first_page->inuse);
+ VM_BUG_ON_PAGE(!is_first_page(first_page), first_page);
+ VM_BUG_ON_PAGE(first_page->inuse, first_page);
head_extra = (struct page *)page_private(first_page);
@@ -921,7 +920,8 @@ static void init_zspage(struct page *first_page, struct size_class *class)
unsigned long off = 0;
struct page *page = first_page;
- BUG_ON(!is_first_page(first_page));
+ VM_BUG_ON_PAGE(!is_first_page(first_page), first_page);
+
while (page) {
struct page *next_page;
struct link_free *link;
@@ -1238,7 +1238,7 @@ static bool can_merge(struct size_class *prev, int size, int pages_per_zspage)
static bool zspage_full(struct page *first_page)
{
- BUG_ON(!is_first_page(first_page));
+ VM_BUG_ON_PAGE(!is_first_page(first_page), first_page);
return first_page->inuse == first_page->objects;
}
@@ -1276,14 +1276,12 @@ void *zs_map_object(struct zs_pool *pool, unsigned long handle,
struct page *pages[2];
void *ret;
- BUG_ON(!handle);
-
/*
* Because we use per-cpu mapping areas shared among the
* pools/users, we can't allow mapping in interrupt context
* because it can corrupt another users mappings.
*/
- BUG_ON(in_interrupt());
+ WARN_ON_ONCE(in_interrupt());
/* From now on, migration cannot move the object */
pin_tag(handle);
@@ -1327,8 +1325,6 @@ void zs_unmap_object(struct zs_pool *pool, unsigned long handle)
struct size_class *class;
struct mapping_area *area;
- BUG_ON(!handle);
-
obj = handle_to_obj(handle);
obj_to_location(obj, &page, &obj_idx);
get_zspage_mapping(get_first_page(page), &class_idx, &fg);
@@ -1448,8 +1444,6 @@ static void obj_free(struct zs_pool *pool, struct size_class *class,
unsigned long f_objidx, f_offset;
void *vaddr;
- BUG_ON(!obj);
-
obj &= ~OBJ_ALLOCATED_TAG;
obj_to_location(obj, &f_page, &f_objidx);
first_page = get_first_page(f_page);
@@ -1549,7 +1543,6 @@ static void zs_object_copy(unsigned long dst, unsigned long src,
kunmap_atomic(d_addr);
kunmap_atomic(s_addr);
s_page = get_next_page(s_page);
- BUG_ON(!s_page);
s_addr = kmap_atomic(s_page);
d_addr = kmap_atomic(d_page);
s_size = class->size - written;
@@ -1559,7 +1552,6 @@ static void zs_object_copy(unsigned long dst, unsigned long src,
if (d_off >= PAGE_SIZE) {
kunmap_atomic(d_addr);
d_page = get_next_page(d_page);
- BUG_ON(!d_page);
d_addr = kmap_atomic(d_page);
d_size = class->size - written;
d_off = 0;
@@ -1694,8 +1686,6 @@ static enum fullness_group putback_zspage(struct zs_pool *pool,
{
enum fullness_group fullness;
- BUG_ON(!is_first_page(first_page));
-
fullness = get_fullness_group(first_page);
insert_zspage(first_page, class, fullness);
set_zspage_mapping(first_page, class->index, fullness);
@@ -1756,8 +1746,6 @@ static void __zs_compact(struct zs_pool *pool, struct size_class *class)
spin_lock(&class->lock);
while ((src_page = isolate_source_page(class))) {
- BUG_ON(!is_first_page(src_page));
-
if (!zs_can_compact(class))
break;
--
1.9.1
^ permalink raw reply related
* [PATCH v2 02/18] zsmalloc: use first_page rather than page
From: Minchan Kim @ 2016-03-21 6:30 UTC (permalink / raw)
To: Andrew Morton
Cc: Rik van Riel, YiPing Xu, aquini, rknize, Sergey Senozhatsky,
Chan Gyun Jeong, Minchan Kim, Hugh Dickins, linux-kernel, Al Viro,
virtualization, bfields, linux-mm, Gioh Kim, koct9i, Sangseok Lee,
jlayton, Joonsoo Kim, Vlastimil Babka, Mel Gorman
In-Reply-To: <1458541867-27380-1-git-send-email-minchan@kernel.org>
This patch cleans up function parameter "struct page".
Many functions of zsmalloc expects that page paramter is "first_page"
so use "first_page" rather than "page" for code readability.
Reviewed-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
Signed-off-by: Minchan Kim <minchan@kernel.org>
---
mm/zsmalloc.c | 62 ++++++++++++++++++++++++++++++-----------------------------
1 file changed, 32 insertions(+), 30 deletions(-)
diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c
index e72efb109fde..b09a80d398c9 100644
--- a/mm/zsmalloc.c
+++ b/mm/zsmalloc.c
@@ -413,26 +413,28 @@ static int is_last_page(struct page *page)
return PagePrivate2(page);
}
-static void get_zspage_mapping(struct page *page, unsigned int *class_idx,
+static void get_zspage_mapping(struct page *first_page,
+ unsigned int *class_idx,
enum fullness_group *fullness)
{
unsigned long m;
- BUG_ON(!is_first_page(page));
+ BUG_ON(!is_first_page(first_page));
- m = (unsigned long)page->mapping;
+ m = (unsigned long)first_page->mapping;
*fullness = m & FULLNESS_MASK;
*class_idx = (m >> FULLNESS_BITS) & CLASS_IDX_MASK;
}
-static void set_zspage_mapping(struct page *page, unsigned int class_idx,
+static void set_zspage_mapping(struct page *first_page,
+ unsigned int class_idx,
enum fullness_group fullness)
{
unsigned long m;
- BUG_ON(!is_first_page(page));
+ BUG_ON(!is_first_page(first_page));
m = ((class_idx & CLASS_IDX_MASK) << FULLNESS_BITS) |
(fullness & FULLNESS_MASK);
- page->mapping = (struct address_space *)m;
+ first_page->mapping = (struct address_space *)m;
}
/*
@@ -625,14 +627,14 @@ static inline void zs_pool_stat_destroy(struct zs_pool *pool)
* the pool (not yet implemented). This function returns fullness
* status of the given page.
*/
-static enum fullness_group get_fullness_group(struct page *page)
+static enum fullness_group get_fullness_group(struct page *first_page)
{
int inuse, max_objects;
enum fullness_group fg;
- BUG_ON(!is_first_page(page));
+ BUG_ON(!is_first_page(first_page));
- inuse = page->inuse;
- max_objects = page->objects;
+ inuse = first_page->inuse;
+ max_objects = first_page->objects;
if (inuse == 0)
fg = ZS_EMPTY;
@@ -652,12 +654,12 @@ static enum fullness_group get_fullness_group(struct page *page)
* have. This functions inserts the given zspage into the freelist
* identified by <class, fullness_group>.
*/
-static void insert_zspage(struct page *page, struct size_class *class,
+static void insert_zspage(struct page *first_page, struct size_class *class,
enum fullness_group fullness)
{
struct page **head;
- BUG_ON(!is_first_page(page));
+ BUG_ON(!is_first_page(first_page));
if (fullness >= _ZS_NR_FULLNESS_GROUPS)
return;
@@ -667,7 +669,7 @@ static void insert_zspage(struct page *page, struct size_class *class,
head = &class->fullness_list[fullness];
if (!*head) {
- *head = page;
+ *head = first_page;
return;
}
@@ -675,21 +677,21 @@ static void insert_zspage(struct page *page, struct size_class *class,
* We want to see more ZS_FULL pages and less almost
* empty/full. Put pages with higher ->inuse first.
*/
- list_add_tail(&page->lru, &(*head)->lru);
- if (page->inuse >= (*head)->inuse)
- *head = page;
+ list_add_tail(&first_page->lru, &(*head)->lru);
+ if (first_page->inuse >= (*head)->inuse)
+ *head = first_page;
}
/*
* This function removes the given zspage from the freelist identified
* by <class, fullness_group>.
*/
-static void remove_zspage(struct page *page, struct size_class *class,
+static void remove_zspage(struct page *first_page, struct size_class *class,
enum fullness_group fullness)
{
struct page **head;
- BUG_ON(!is_first_page(page));
+ BUG_ON(!is_first_page(first_page));
if (fullness >= _ZS_NR_FULLNESS_GROUPS)
return;
@@ -698,11 +700,11 @@ static void remove_zspage(struct page *page, struct size_class *class,
BUG_ON(!*head);
if (list_empty(&(*head)->lru))
*head = NULL;
- else if (*head == page)
+ else if (*head == first_page)
*head = (struct page *)list_entry((*head)->lru.next,
struct page, lru);
- list_del_init(&page->lru);
+ list_del_init(&first_page->lru);
zs_stat_dec(class, fullness == ZS_ALMOST_EMPTY ?
CLASS_ALMOST_EMPTY : CLASS_ALMOST_FULL, 1);
}
@@ -717,21 +719,21 @@ static void remove_zspage(struct page *page, struct size_class *class,
* fullness group.
*/
static enum fullness_group fix_fullness_group(struct size_class *class,
- struct page *page)
+ struct page *first_page)
{
int class_idx;
enum fullness_group currfg, newfg;
- BUG_ON(!is_first_page(page));
+ BUG_ON(!is_first_page(first_page));
- get_zspage_mapping(page, &class_idx, &currfg);
- newfg = get_fullness_group(page);
+ get_zspage_mapping(first_page, &class_idx, &currfg);
+ newfg = get_fullness_group(first_page);
if (newfg == currfg)
goto out;
- remove_zspage(page, class, currfg);
- insert_zspage(page, class, newfg);
- set_zspage_mapping(page, class_idx, newfg);
+ remove_zspage(first_page, class, currfg);
+ insert_zspage(first_page, class, newfg);
+ set_zspage_mapping(first_page, class_idx, newfg);
out:
return newfg;
@@ -1234,11 +1236,11 @@ static bool can_merge(struct size_class *prev, int size, int pages_per_zspage)
return true;
}
-static bool zspage_full(struct page *page)
+static bool zspage_full(struct page *first_page)
{
- BUG_ON(!is_first_page(page));
+ BUG_ON(!is_first_page(first_page));
- return page->inuse == page->objects;
+ return first_page->inuse == first_page->objects;
}
unsigned long zs_get_total_pages(struct zs_pool *pool)
--
1.9.1
^ permalink raw reply related
* [PATCH v2 01/18] mm: use put_page to free page instead of putback_lru_page
From: Minchan Kim @ 2016-03-21 6:30 UTC (permalink / raw)
To: Andrew Morton
Cc: Rik van Riel, YiPing Xu, aquini, rknize, Sergey Senozhatsky,
Chan Gyun Jeong, Minchan Kim, Hugh Dickins, linux-kernel, Al Viro,
virtualization, bfields, linux-mm, Gioh Kim, koct9i, Sangseok Lee,
jlayton, Naoya Horiguchi, Joonsoo Kim, Vlastimil Babka,
Mel Gorman
In-Reply-To: <1458541867-27380-1-git-send-email-minchan@kernel.org>
Procedure of page migration is as follows:
First of all, it should isolate a page from LRU and try to
migrate the page. If it is successful, it releases the page
for freeing. Otherwise, it should put the page back to LRU
list.
For LRU pages, we have used putback_lru_page for both freeing
and putback to LRU list. It's okay because put_page is aware of
LRU list so if it releases last refcount of the page, it removes
the page from LRU list. However, It makes unnecessary operations
(e.g., lru_cache_add, pagevec and flags operations. It would be
not significant but no worth to do) and harder to support new
non-lru page migration because put_page isn't aware of non-lru
page's data structure.
To solve the problem, we can add new hook in put_page with
PageMovable flags check but it can increase overhead in
hot path and needs new locking scheme to stabilize the flag check
with put_page.
So, this patch cleans it up to divide two semantic(ie, put and putback).
If migration is successful, use put_page instead of putback_lru_page and
use putback_lru_page only on failure. That makes code more readable
and doesn't add overhead in put_page.
Comment from Vlastimil
"Yeah, and compaction (perhaps also other migration users) has to drain
the lru pvec... Getting rid of this stuff is worth even by itself."
Cc: Mel Gorman <mgorman@suse.de>
Cc: Hugh Dickins <hughd@google.com>
Cc: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>
Acked-by: Vlastimil Babka <vbabka@suse.cz>
Signed-off-by: Minchan Kim <minchan@kernel.org>
---
mm/migrate.c | 50 +++++++++++++++++++++++++++++++-------------------
1 file changed, 31 insertions(+), 19 deletions(-)
diff --git a/mm/migrate.c b/mm/migrate.c
index 6c822a7b27e0..b65c84267ce0 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -913,6 +913,14 @@ static int __unmap_and_move(struct page *page, struct page *newpage,
put_anon_vma(anon_vma);
unlock_page(page);
out:
+ /* If migration is scucessful, move newpage to right list */
+ if (rc == MIGRATEPAGE_SUCCESS) {
+ if (unlikely(__is_movable_balloon_page(newpage)))
+ put_page(newpage);
+ else
+ putback_lru_page(newpage);
+ }
+
return rc;
}
@@ -946,6 +954,12 @@ static ICE_noinline int unmap_and_move(new_page_t get_new_page,
if (page_count(page) == 1) {
/* page was freed from under us. So we are done. */
+ ClearPageActive(page);
+ ClearPageUnevictable(page);
+ if (put_new_page)
+ put_new_page(newpage, private);
+ else
+ put_page(newpage);
goto out;
}
@@ -958,10 +972,8 @@ static ICE_noinline int unmap_and_move(new_page_t get_new_page,
}
rc = __unmap_and_move(page, newpage, force, mode);
- if (rc == MIGRATEPAGE_SUCCESS) {
- put_new_page = NULL;
+ if (rc == MIGRATEPAGE_SUCCESS)
set_page_owner_migrate_reason(newpage, reason);
- }
out:
if (rc != -EAGAIN) {
@@ -974,28 +986,28 @@ static ICE_noinline int unmap_and_move(new_page_t get_new_page,
list_del(&page->lru);
dec_zone_page_state(page, NR_ISOLATED_ANON +
page_is_file_cache(page));
- /* Soft-offlined page shouldn't go through lru cache list */
+ }
+
+ /*
+ * If migration is successful, drop the reference grabbed during
+ * isolation. Otherwise, restore the page to LRU list unless we
+ * want to retry.
+ */
+ if (rc == MIGRATEPAGE_SUCCESS) {
+ put_page(page);
if (reason == MR_MEMORY_FAILURE) {
- put_page(page);
if (!test_set_page_hwpoison(page))
num_poisoned_pages_inc();
- } else
+ }
+ } else {
+ if (rc != -EAGAIN)
putback_lru_page(page);
+ if (put_new_page)
+ put_new_page(newpage, private);
+ else
+ put_page(newpage);
}
- /*
- * If migration was not successful and there's a freeing callback, use
- * it. Otherwise, putback_lru_page() will drop the reference grabbed
- * during isolation.
- */
- if (put_new_page)
- put_new_page(newpage, private);
- else if (unlikely(__is_movable_balloon_page(newpage))) {
- /* drop our reference, page already in the balloon */
- put_page(newpage);
- } else
- putback_lru_page(newpage);
-
if (result) {
if (rc)
*result = rc;
--
1.9.1
^ permalink raw reply related
* [PATCH v2 00/18] Support non-lru page migration
From: Minchan Kim @ 2016-03-21 6:30 UTC (permalink / raw)
To: Andrew Morton
Cc: Rik van Riel, YiPing Xu, aquini, rknize, Sergey Senozhatsky,
Chan Gyun Jeong, Minchan Kim, Hugh Dickins, linux-kernel, Al Viro,
virtualization, bfields, linux-mm, Gioh Kim, koct9i, Sangseok Lee,
jlayton, Joonsoo Kim, Vlastimil Babka, Mel Gorman
Recently, I got many reports about perfermance degradation
in embedded system(Android mobile phone, webOS TV and so on)
and failed to fork easily.
The problem was fragmentation caused by zram and GPU driver
pages. Their pages cannot be migrated so compaction cannot
work well, either so reclaimer ends up shrinking all of working
set pages. It made system very slow and even to fail to fork
easily.
Other pain point is that they cannot work with CMA.
Most of CMA memory space could be idle(ie, it could be used
for movable pages unless driver is using) but if driver(i.e.,
zram) cannot migrate his page, that memory space could be
wasted. In our product which has big CMA memory, it reclaims
zones too exccessively although there are lots of free space
in CMA so system was very slow easily.
To solve these problem, this patch try to add facility to
migrate non-lru pages via introducing new friend functions
of migratepage in address_space_operation and new page flags.
(isolate_page, putback_page)
(PG_movable, PG_isolated)
For details, please read description in
"mm/compaction: support non-lru movable page migration".
Originally, Gioh Kim tried to support this feature but he moved
so I took over the work. But I took many code from his work and
changed a little bit.
Thanks, Gioh!
And I should mention Konstantin Khlebnikov. He really heped Gioh
at that time so he should deserve to have many credit, too.
Thanks, Konstantin!
This patchset consists of five parts
1. clean up migration
mm: use put_page to free page instead of putback_lru_page
2. zsmalloc clean-up for preparing page migration
zsmalloc: use first_page rather than page
zsmalloc: clean up many BUG_ON
zsmalloc: reordering function parameter
zsmalloc: remove unused pool param in obj_free
zsmalloc: keep max_object in size_class
zsmalloc: squeeze inuse into page->mapping
zsmalloc: squeeze freelist into page->mapping
zsmalloc: move struct zs_meta from mapping to freelist
zsmalloc: factor page chain functionality out
zsmalloc: separate free_zspage from putback_zspage
zsmalloc: zs_compact refactoring
3. add non-lru page migration feature
mm/compaction: support non-lru movable page migration
4. rework KVM memory-ballooning
mm/balloon: use general movable page feature into balloon
5. add zsmalloc page migration
zsmalloc: migrate head page of zspage
zsmalloc: use single linked list for page chain
zsmalloc: migrate tail pages in zspage
zram: use __GFP_MOVABLE for memory allocation
* From v1
* rebase on v4.5-mmotm-2016-03-17-15-04
* reordering patches to merge clean-up patches first
* add Acked-by/Reviewed-by from Vlastimil and Sergey
* use each own mount model instead of reusing anon_inode_fs - Al Viro
* small changes - YiPing, Gioh
Minchan Kim (18):
mm: use put_page to free page instead of putback_lru_page
zsmalloc: use first_page rather than page
zsmalloc: clean up many BUG_ON
zsmalloc: reordering function parameter
zsmalloc: remove unused pool param in obj_free
zsmalloc: keep max_object in size_class
zsmalloc: squeeze inuse into page->mapping
zsmalloc: squeeze freelist into page->mapping
zsmalloc: move struct zs_meta from mapping to freelist
zsmalloc: factor page chain functionality out
zsmalloc: separate free_zspage from putback_zspage
zsmalloc: zs_compact refactoring
mm/compaction: support non-lru movable page migration
mm/balloon: use general movable page feature into balloon
zsmalloc: migrate head page of zspage
zsmalloc: use single linked list for page chain
zsmalloc: migrate tail pages in zspage
zram: use __GFP_MOVABLE for memory allocation
Documentation/filesystems/Locking | 4 +
Documentation/filesystems/vfs.txt | 5 +
drivers/block/zram/zram_drv.c | 3 +-
drivers/virtio/virtio_balloon.c | 45 +-
fs/proc/page.c | 3 +
include/linux/balloon_compaction.h | 47 +-
include/linux/fs.h | 2 +
include/linux/migrate.h | 2 +
include/linux/page-flags.h | 41 +-
include/uapi/linux/kernel-page-flags.h | 1 +
include/uapi/linux/magic.h | 2 +
mm/balloon_compaction.c | 101 +--
mm/compaction.c | 15 +-
mm/migrate.c | 198 +++--
mm/vmscan.c | 2 +-
mm/zsmalloc.c | 1338 +++++++++++++++++++++++---------
16 files changed, 1284 insertions(+), 525 deletions(-)
--
1.9.1
^ permalink raw reply
* [PULL] virtio/vhost: new features, performance improvements, cleanups
From: Michael S. Tsirkin @ 2016-03-20 13:58 UTC (permalink / raw)
To: Linus Torvalds
Cc: pmladek, kvm, geliangtang, netdev, mst, sebott, linux-kernel,
pmladek, virtualization, borntraeger, luto, pbonzini, pabeni,
schwidefsky, gkurz
The following changes since commit e1f33be9186363da7955bcb5f0b03e6685544c50:
vhost: fix error path in vhost_init_used() (2016-03-02 17:01:49 +0200)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost.git tags/for_linus
for you to fetch changes up to c67f5db82027ba6d2ea4ac9176bc45996a03ae6a:
virtio_net: replace netdev_alloc_skb_ip_align() with napi_alloc_skb() (2016-03-17 17:42:00 +0200)
----------------------------------------------------------------
virtio/vhost: new features, performance improvements, cleanups
This adds basic polling support for vhost.
Reworks virtio to optionally use DMA API, fixing it on Xen.
Balloon stats gained a new entry.
Using the new napi_alloc_skb speeds up virtio net.
virtio blk stats can now be read while another VCPU
us busy inflating or deflating the balloon.
Plus misc cleanups in various places.
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
----------------------------------------------------------------
Andy Lutomirski (6):
vring: Introduce vring_use_dma_api()
virtio_ring: Support DMA APIs
virtio: Add improved queue allocation API
virtio_mmio: Use the DMA API if enabled
virtio_pci: Use the DMA API if enabled
vring: Use the DMA API on Xen
Christian Borntraeger (3):
dma: Provide simple noop dma ops
alpha/dma: use common noop dma ops
s390/dma: Allow per device dma ops
Cornelia Huck (1):
virtio/s390: size of SET_IND payload
Geliang Tang (1):
virtio/s390: use dev_to_virtio
Greg Kurz (2):
vhost: rename cross-endian helpers
vhost: rename vhost_init_used()
Jason Wang (3):
vhost: introduce vhost_has_work()
vhost: introduce vhost_vq_avail_empty()
vhost_net: basic polling support
Michael S. Tsirkin (1):
virtio_blk: VIRTIO_BLK_F_WCE->VIRTIO_BLK_F_FLUSH
Paolo Abeni (1):
virtio_net: replace netdev_alloc_skb_ip_align() with napi_alloc_skb()
Petr Mladek (2):
virtio_balloon: Use a workqueue instead of "vballoon" kthread
virtio_balloon: Allow to resize and update the balloon stats in parallel
arch/s390/include/asm/device.h | 6 +-
arch/s390/include/asm/dma-mapping.h | 6 +-
drivers/vhost/vhost.h | 5 +-
drivers/virtio/virtio_pci_common.h | 6 -
include/linux/dma-mapping.h | 2 +
include/linux/virtio.h | 23 +-
include/linux/virtio_ring.h | 35 +++
include/uapi/linux/vhost.h | 6 +
include/uapi/linux/virtio_blk.h | 6 +-
tools/virtio/linux/dma-mapping.h | 17 ++
arch/alpha/kernel/pci-noop.c | 46 +---
arch/s390/pci/pci.c | 1 +
arch/s390/pci/pci_dma.c | 4 +-
drivers/block/virtio_blk.c | 11 +-
drivers/net/virtio_net.c | 2 +-
drivers/s390/virtio/virtio_ccw.c | 15 +-
drivers/vhost/net.c | 80 ++++++-
drivers/vhost/scsi.c | 2 +-
drivers/vhost/test.c | 2 +-
drivers/vhost/vhost.c | 69 +++++-
drivers/virtio/virtio_balloon.c | 122 +++++-----
drivers/virtio/virtio_mmio.c | 67 ++----
drivers/virtio/virtio_pci_legacy.c | 42 ++--
drivers/virtio/virtio_pci_modern.c | 61 ++---
drivers/virtio/virtio_ring.c | 439 +++++++++++++++++++++++++++++++-----
lib/dma-noop.c | 75 ++++++
arch/s390/Kconfig | 5 +-
drivers/virtio/Kconfig | 2 +-
lib/Makefile | 1 +
29 files changed, 823 insertions(+), 335 deletions(-)
create mode 100644 tools/virtio/linux/dma-mapping.h
create mode 100644 lib/dma-noop.c
^ permalink raw reply
* Re: [net-next v2] virtio_net: replace netdev_alloc_skb_ip_align() with napi_alloc_skb()
From: Michael S. Tsirkin @ 2016-03-20 12:28 UTC (permalink / raw)
To: Paolo Abeni; +Cc: netdev, Hannes Frederic Sowa, virtualization
In-Reply-To: <98c94ca899603eb4212c44aa1a658825198ed49a.1458290241.git.pabeni@redhat.com>
On Fri, Mar 18, 2016 at 04:42:48PM +0100, Paolo Abeni wrote:
> This gives small but noticeable rx performance improvement (2-3%)
> and will allow exploiting future napi improvement.
>
> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
I am not sure this is necessarily worth doing for this dumb hardware.
I queued v1 in vhost tree for now, let's see some performance
numbers before we start changing about other paths.
> --
> v2: replace also netdev_alloc_skb_ip_align() invocation in
> add_recvbuf_small(), suggested by Venkatesh Srinivas
> ---
> drivers/net/virtio_net.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> index fb0eae4..100e039 100644
> --- a/drivers/net/virtio_net.c
> +++ b/drivers/net/virtio_net.c
> @@ -260,7 +260,7 @@ static struct sk_buff *page_to_skb(struct virtnet_info *vi,
> p = page_address(page) + offset;
>
> /* copy small packet so we can reuse these pages for small data */
> - skb = netdev_alloc_skb_ip_align(vi->dev, GOOD_COPY_LEN);
> + skb = napi_alloc_skb(&rq->napi, GOOD_COPY_LEN);
> if (unlikely(!skb))
> return NULL;
>
> @@ -541,7 +541,7 @@ static int add_recvbuf_small(struct virtnet_info *vi, struct receive_queue *rq,
> struct virtio_net_hdr_mrg_rxbuf *hdr;
> int err;
>
> - skb = __netdev_alloc_skb_ip_align(vi->dev, GOOD_PACKET_LEN, gfp);
> + skb = __napi_alloc_skb(&rq->napi, GOOD_PACKET_LEN, gfp);
> if (unlikely(!skb))
> return -ENOMEM;
>
> --
> 1.8.3.1
^ permalink raw reply
* Re: [PATCH] gpu/drm: Use u64_to_user_pointer
From: kbuild test robot @ 2016-03-18 17:46 UTC (permalink / raw)
To: Joe Perches
Cc: Alexandre Courbot, Terje Bergström, Stephen Warren,
David Airlie, Gustavo Padovan, dri-devel, linux-kernel,
Daniel Vetter, virtualization, Rob Clark, Thierry Reding,
kbuild-all, Greg Kroah-Hartman, linux-tegra, Russell King,
Andrew Morton
In-Reply-To: <b70b7949e8344abe13d85d6e8e5a8e11bb9c5f02.1458321299.git.joe@perches.com>
[-- Attachment #1: Type: text/plain, Size: 7152 bytes --]
Hi Joe,
[auto build test WARNING on drm/drm-next]
[also build test WARNING on next-20160318]
[cannot apply to v4.5]
[if your patch is applied to the wrong git tree, please drop us a note to help improving the system]
url: https://github.com/0day-ci/linux/commits/Joe-Perches/gpu-drm-Use-u64_to_user_pointer/20160319-012749
base: git://people.freedesktop.org/~airlied/linux.git drm-next
config: mips-allmodconfig (attached as .config)
reproduce:
wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=mips
All warnings (new ones prefixed by >>):
In file included from include/linux/uaccess.h:5:0,
from include/linux/highmem.h:8,
from include/drm/drmP.h:40,
from drivers/gpu/drm/vc4/vc4_drv.h:9,
from drivers/gpu/drm/vc4/vc4_bo.c:21:
drivers/gpu/drm/vc4/vc4_bo.c: In function 'vc4_create_shader_bo_ioctl':
drivers/gpu/drm/vc4/vc4_bo.c:503:7: error: implicit declaration of function 'u64_to_user_ptr' [-Werror=implicit-function-declaration]
u64_to_user_ptr(args->data),
^
arch/mips/include/asm/uaccess.h:1161:15: note: in definition of macro 'copy_from_user'
__cu_from = (from); \
^
>> arch/mips/include/asm/uaccess.h:1161:12: warning: assignment makes pointer from integer without a cast [-Wint-conversion]
__cu_from = (from); \
^
drivers/gpu/drm/vc4/vc4_bo.c:502:6: note: in expansion of macro 'copy_from_user'
if (copy_from_user(bo->base.vaddr,
^
cc1: some warnings being treated as errors
--
In file included from arch/mips/include/asm/module.h:6:0,
from include/linux/module.h:24,
from drivers/gpu/drm/vc4/vc4_gem.c:24:
drivers/gpu/drm/vc4/vc4_gem.c: In function 'vc4_get_hang_state_ioctl':
drivers/gpu/drm/vc4/vc4_gem.c:123:19: error: implicit declaration of function 'u64_to_user_ptr' [-Werror=implicit-function-declaration]
if (copy_to_user(u64_to_user_ptr(get_state->bo),
^
arch/mips/include/asm/uaccess.h:930:13: note: in definition of macro 'copy_to_user'
__cu_to = (to); \
^
arch/mips/include/asm/uaccess.h:930:10: warning: assignment makes pointer from integer without a cast [-Wint-conversion]
__cu_to = (to); \
^
drivers/gpu/drm/vc4/vc4_gem.c:123:6: note: in expansion of macro 'copy_to_user'
if (copy_to_user(u64_to_user_ptr(get_state->bo),
^
drivers/gpu/drm/vc4/vc4_gem.c: In function 'vc4_cl_lookup_bos':
>> arch/mips/include/asm/uaccess.h:1161:12: warning: assignment makes pointer from integer without a cast [-Wint-conversion]
__cu_from = (from); \
^
drivers/gpu/drm/vc4/vc4_gem.c:552:8: note: in expansion of macro 'copy_from_user'
ret = copy_from_user(handles,
^
drivers/gpu/drm/vc4/vc4_gem.c: In function 'vc4_get_bcl':
>> arch/mips/include/asm/uaccess.h:1161:12: warning: assignment makes pointer from integer without a cast [-Wint-conversion]
__cu_from = (from); \
^
drivers/gpu/drm/vc4/vc4_gem.c:626:6: note: in expansion of macro 'copy_from_user'
if (copy_from_user(bin,
^
>> arch/mips/include/asm/uaccess.h:1161:12: warning: assignment makes pointer from integer without a cast [-Wint-conversion]
__cu_from = (from); \
^
drivers/gpu/drm/vc4/vc4_gem.c:633:6: note: in expansion of macro 'copy_from_user'
if (copy_from_user(exec->shader_rec_u,
^
>> arch/mips/include/asm/uaccess.h:1161:12: warning: assignment makes pointer from integer without a cast [-Wint-conversion]
__cu_from = (from); \
^
drivers/gpu/drm/vc4/vc4_gem.c:640:6: note: in expansion of macro 'copy_from_user'
if (copy_from_user(exec->uniforms_u,
^
cc1: some warnings being treated as errors
vim +1161 arch/mips/include/asm/uaccess.h
^1da177e include/asm-mips/uaccess.h Linus Torvalds 2005-04-16 1145 *
^1da177e include/asm-mips/uaccess.h Linus Torvalds 2005-04-16 1146 * Copy data from user space to kernel space.
^1da177e include/asm-mips/uaccess.h Linus Torvalds 2005-04-16 1147 *
^1da177e include/asm-mips/uaccess.h Linus Torvalds 2005-04-16 1148 * Returns number of bytes that could not be copied.
^1da177e include/asm-mips/uaccess.h Linus Torvalds 2005-04-16 1149 * On success, this will be zero.
^1da177e include/asm-mips/uaccess.h Linus Torvalds 2005-04-16 1150 *
^1da177e include/asm-mips/uaccess.h Linus Torvalds 2005-04-16 1151 * If some data could not be copied, this function will pad the copied
^1da177e include/asm-mips/uaccess.h Linus Torvalds 2005-04-16 1152 * data to the requested size using zero bytes.
^1da177e include/asm-mips/uaccess.h Linus Torvalds 2005-04-16 1153 */
^1da177e include/asm-mips/uaccess.h Linus Torvalds 2005-04-16 1154 #define copy_from_user(to, from, n) \
^1da177e include/asm-mips/uaccess.h Linus Torvalds 2005-04-16 1155 ({ \
^1da177e include/asm-mips/uaccess.h Linus Torvalds 2005-04-16 1156 void *__cu_to; \
fe00f943 include/asm-mips/uaccess.h Ralf Baechle 2005-03-01 1157 const void __user *__cu_from; \
^1da177e include/asm-mips/uaccess.h Linus Torvalds 2005-04-16 1158 long __cu_len; \
^1da177e include/asm-mips/uaccess.h Linus Torvalds 2005-04-16 1159 \
^1da177e include/asm-mips/uaccess.h Linus Torvalds 2005-04-16 1160 __cu_to = (to); \
^1da177e include/asm-mips/uaccess.h Linus Torvalds 2005-04-16 @1161 __cu_from = (from); \
^1da177e include/asm-mips/uaccess.h Linus Torvalds 2005-04-16 1162 __cu_len = (n); \
12060666 arch/mips/include/asm/uaccess.h Paul Burton 2015-05-24 1163 if (eva_kernel_access()) { \
05c65160 arch/mips/include/asm/uaccess.h Markos Chandras 2013-12-11 1164 __cu_len = __invoke_copy_from_kernel(__cu_to, \
05c65160 arch/mips/include/asm/uaccess.h Markos Chandras 2013-12-11 1165 __cu_from, \
05c65160 arch/mips/include/asm/uaccess.h Markos Chandras 2013-12-11 1166 __cu_len); \
05c65160 arch/mips/include/asm/uaccess.h Markos Chandras 2013-12-11 1167 } else { \
ef41f460 arch/mips/include/asm/uaccess.h Ralf Baechle 2009-04-28 1168 if (access_ok(VERIFY_READ, __cu_from, __cu_len)) { \
ef41f460 arch/mips/include/asm/uaccess.h Ralf Baechle 2009-04-28 1169 might_fault(); \
:::::: The code at line 1161 was first introduced by commit
:::::: 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 Linux-2.6.12-rc2
:::::: TO: Linus Torvalds <torvalds@ppc970.osdl.org>
:::::: CC: Linus Torvalds <torvalds@ppc970.osdl.org>
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 40472 bytes --]
[-- Attachment #3: Type: text/plain, Size: 183 bytes --]
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
^ permalink raw reply
* Re: [PATCH] gpu/drm: Use u64_to_user_pointer
From: Joe Perches @ 2016-03-18 17:43 UTC (permalink / raw)
To: kbuild test robot
Cc: Alexandre Courbot, Terje Bergström, Stephen Warren,
David Airlie, Gustavo Padovan, dri-devel, linux-kernel,
Daniel Vetter, virtualization, Rob Clark, Thierry Reding,
kbuild-all, Greg Kroah-Hartman, linux-tegra, Russell King,
Andrew Morton
In-Reply-To: <201603190148.px58QxiJ%fengguang.wu@intel.com>
On Sat, 2016-03-19 at 01:39 +0800, kbuild test robot wrote:
> Hi Joe,
>
> [auto build test WARNING on drm/drm-next]
> [also build test WARNING on next-20160318]
> [cannot apply to v4.5]
> [if your patch is applied to the wrong git tree, please drop us a
> note to help improving the system]
Thanks, but this depends on Gustavo's patches too.
^ permalink raw reply
* Re: [PATCH] gpu/drm: Use u64_to_user_pointer
From: kbuild test robot @ 2016-03-18 17:43 UTC (permalink / raw)
To: Joe Perches
Cc: Alexandre Courbot, Terje Bergström, Stephen Warren,
David Airlie, Gustavo Padovan, dri-devel, linux-kernel,
Daniel Vetter, virtualization, Rob Clark, Thierry Reding,
kbuild-all, Greg Kroah-Hartman, linux-tegra, Russell King,
Andrew Morton
In-Reply-To: <b70b7949e8344abe13d85d6e8e5a8e11bb9c5f02.1458321299.git.joe@perches.com>
[-- Attachment #1: Type: text/plain, Size: 8037 bytes --]
Hi Joe,
[auto build test ERROR on drm/drm-next]
[also build test ERROR on next-20160318]
[cannot apply to v4.5]
[if your patch is applied to the wrong git tree, please drop us a note to help improving the system]
url: https://github.com/0day-ci/linux/commits/Joe-Perches/gpu-drm-Use-u64_to_user_pointer/20160319-012749
base: git://people.freedesktop.org/~airlied/linux.git drm-next
config: xtensa-allmodconfig (attached as .config)
reproduce:
wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=xtensa
All error/warnings (new ones prefixed by >>):
drivers/gpu/drm/vc4/vc4_bo.c: In function 'vc4_create_shader_bo_ioctl':
>> drivers/gpu/drm/vc4/vc4_bo.c:502:2: error: implicit declaration of function 'u64_to_user_ptr' [-Werror=implicit-function-declaration]
if (copy_from_user(bo->base.vaddr,
^
In file included from include/linux/uaccess.h:5:0,
from include/linux/highmem.h:8,
from include/drm/drmP.h:40,
from drivers/gpu/drm/vc4/vc4_drv.h:9,
from drivers/gpu/drm/vc4/vc4_bo.c:21:
>> arch/xtensa/include/asm/uaccess.h:429:37: warning: passing argument 2 of '__generic_copy_from_user' makes pointer from integer without a cast
#define copy_from_user(to, from, n) __generic_copy_from_user((to), (from), (n))
^
>> drivers/gpu/drm/vc4/vc4_bo.c:502:6: note: in expansion of macro 'copy_from_user'
if (copy_from_user(bo->base.vaddr,
^
arch/xtensa/include/asm/uaccess.h:418:1: note: expected 'const void *' but argument is of type 'int'
__generic_copy_from_user(void *to, const void *from, unsigned long n)
^
cc1: some warnings being treated as errors
--
drivers/gpu/drm/vc4/vc4_gem.c: In function 'vc4_get_hang_state_ioctl':
>> drivers/gpu/drm/vc4/vc4_gem.c:123:2: error: implicit declaration of function 'u64_to_user_ptr' [-Werror=implicit-function-declaration]
if (copy_to_user(u64_to_user_ptr(get_state->bo),
^
In file included from include/linux/uaccess.h:5:0,
from include/linux/highmem.h:8,
from include/drm/drmP.h:40,
from drivers/gpu/drm/vc4/vc4_drv.h:9,
from drivers/gpu/drm/vc4/vc4_gem.c:31:
>> arch/xtensa/include/asm/uaccess.h:428:35: warning: passing argument 1 of '__generic_copy_to_user' makes pointer from integer without a cast
#define copy_to_user(to, from, n) __generic_copy_to_user((to), (from), (n))
^
>> drivers/gpu/drm/vc4/vc4_gem.c:123:6: note: in expansion of macro 'copy_to_user'
if (copy_to_user(u64_to_user_ptr(get_state->bo),
^
arch/xtensa/include/asm/uaccess.h:409:1: note: expected 'void *' but argument is of type 'int'
__generic_copy_to_user(void *to, const void *from, unsigned long n)
^
drivers/gpu/drm/vc4/vc4_gem.c: In function 'vc4_cl_lookup_bos':
>> arch/xtensa/include/asm/uaccess.h:429:37: warning: passing argument 2 of '__generic_copy_from_user' makes pointer from integer without a cast
#define copy_from_user(to, from, n) __generic_copy_from_user((to), (from), (n))
^
>> drivers/gpu/drm/vc4/vc4_gem.c:552:8: note: in expansion of macro 'copy_from_user'
ret = copy_from_user(handles,
^
arch/xtensa/include/asm/uaccess.h:418:1: note: expected 'const void *' but argument is of type 'int'
__generic_copy_from_user(void *to, const void *from, unsigned long n)
^
drivers/gpu/drm/vc4/vc4_gem.c: In function 'vc4_get_bcl':
>> arch/xtensa/include/asm/uaccess.h:429:37: warning: passing argument 2 of '__generic_copy_from_user' makes pointer from integer without a cast
#define copy_from_user(to, from, n) __generic_copy_from_user((to), (from), (n))
^
drivers/gpu/drm/vc4/vc4_gem.c:626:6: note: in expansion of macro 'copy_from_user'
if (copy_from_user(bin,
^
arch/xtensa/include/asm/uaccess.h:418:1: note: expected 'const void *' but argument is of type 'int'
__generic_copy_from_user(void *to, const void *from, unsigned long n)
^
>> arch/xtensa/include/asm/uaccess.h:429:37: warning: passing argument 2 of '__generic_copy_from_user' makes pointer from integer without a cast
#define copy_from_user(to, from, n) __generic_copy_from_user((to), (from), (n))
^
drivers/gpu/drm/vc4/vc4_gem.c:633:6: note: in expansion of macro 'copy_from_user'
if (copy_from_user(exec->shader_rec_u,
^
arch/xtensa/include/asm/uaccess.h:418:1: note: expected 'const void *' but argument is of type 'int'
__generic_copy_from_user(void *to, const void *from, unsigned long n)
^
>> arch/xtensa/include/asm/uaccess.h:429:37: warning: passing argument 2 of '__generic_copy_from_user' makes pointer from integer without a cast
#define copy_from_user(to, from, n) __generic_copy_from_user((to), (from), (n))
^
drivers/gpu/drm/vc4/vc4_gem.c:640:6: note: in expansion of macro 'copy_from_user'
if (copy_from_user(exec->uniforms_u,
^
arch/xtensa/include/asm/uaccess.h:418:1: note: expected 'const void *' but argument is of type 'int'
__generic_copy_from_user(void *to, const void *from, unsigned long n)
^
cc1: some warnings being treated as errors
--
drivers/gpu/drm/virtio/virtgpu_ioctl.c: In function 'virtio_gpu_execbuffer':
>> drivers/gpu/drm/virtio/virtgpu_ioctl.c:126:3: error: implicit declaration of function 'u64_to_user_ptr' [-Werror=implicit-function-declaration]
user_bo_handles = u64_to_user_ptr(exbuf->bo_handles);
^
>> drivers/gpu/drm/virtio/virtgpu_ioctl.c:126:19: warning: assignment makes pointer from integer without a cast
user_bo_handles = u64_to_user_ptr(exbuf->bo_handles);
^
In file included from include/linux/uaccess.h:5:0,
from include/linux/highmem.h:8,
from include/drm/drmP.h:40,
from drivers/gpu/drm/virtio/virtgpu_ioctl.c:28:
>> arch/xtensa/include/asm/uaccess.h:429:37: warning: passing argument 2 of '__generic_copy_from_user' makes pointer from integer without a cast
#define copy_from_user(to, from, n) __generic_copy_from_user((to), (from), (n))
^
>> drivers/gpu/drm/virtio/virtgpu_ioctl.c:161:6: note: in expansion of macro 'copy_from_user'
if (copy_from_user(buf, u64_to_user_ptr(exbuf->command), exbuf->size)) {
^
arch/xtensa/include/asm/uaccess.h:418:1: note: expected 'const void *' but argument is of type 'int'
__generic_copy_from_user(void *to, const void *from, unsigned long n)
^
cc1: some warnings being treated as errors
vim +/u64_to_user_ptr +502 drivers/gpu/drm/vc4/vc4_bo.c
463873d5 Eric Anholt 2015-11-30 496 }
463873d5 Eric Anholt 2015-11-30 497
463873d5 Eric Anholt 2015-11-30 498 bo = vc4_bo_create(dev, args->size, true);
2c68f1fc Eric Anholt 2016-01-25 499 if (IS_ERR(bo))
2c68f1fc Eric Anholt 2016-01-25 500 return PTR_ERR(bo);
463873d5 Eric Anholt 2015-11-30 501
585cb132 Dan Carpenter 2016-03-08 @502 if (copy_from_user(bo->base.vaddr,
3f3044e5 Joe Perches 2016-03-18 503 u64_to_user_ptr(args->data),
585cb132 Dan Carpenter 2016-03-08 504 args->size)) {
585cb132 Dan Carpenter 2016-03-08 505 ret = -EFAULT;
:::::: The code at line 502 was first introduced by commit
:::::: 585cb132a48190b554aecda2ebc3e2911fcbb665 drm/vc4: Return -EFAULT on copy_from_user() failure
:::::: TO: Dan Carpenter <dan.carpenter@oracle.com>
:::::: CC: Eric Anholt <eric@anholt.net>
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 43845 bytes --]
[-- Attachment #3: Type: text/plain, Size: 183 bytes --]
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
^ permalink raw reply
* Re: [PATCH] gpu/drm: Use u64_to_user_pointer
From: kbuild test robot @ 2016-03-18 17:39 UTC (permalink / raw)
To: Joe Perches
Cc: Alexandre Courbot, Terje Bergström, Stephen Warren,
David Airlie, Gustavo Padovan, dri-devel, linux-kernel,
Daniel Vetter, virtualization, Rob Clark, Thierry Reding,
kbuild-all, Greg Kroah-Hartman, linux-tegra, Russell King,
Andrew Morton
In-Reply-To: <b70b7949e8344abe13d85d6e8e5a8e11bb9c5f02.1458321299.git.joe@perches.com>
[-- Attachment #1: Type: text/plain, Size: 31615 bytes --]
Hi Joe,
[auto build test WARNING on drm/drm-next]
[also build test WARNING on next-20160318]
[cannot apply to v4.5]
[if your patch is applied to the wrong git tree, please drop us a note to help improving the system]
url: https://github.com/0day-ci/linux/commits/Joe-Perches/gpu-drm-Use-u64_to_user_pointer/20160319-012749
base: git://people.freedesktop.org/~airlied/linux.git drm-next
config: m68k-allmodconfig (attached as .config)
reproduce:
wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=m68k
All warnings (new ones prefixed by >>):
drivers/gpu/drm/vc4/vc4_bo.c: In function 'vc4_create_shader_bo_ioctl':
drivers/gpu/drm/vc4/vc4_bo.c:502:2: error: implicit declaration of function 'u64_to_user_ptr' [-Werror=implicit-function-declaration]
if (copy_from_user(bo->base.vaddr,
^
In file included from arch/m68k/include/asm/uaccess.h:4:0,
from include/linux/uaccess.h:5,
from include/linux/highmem.h:8,
from include/drm/drmP.h:40,
from drivers/gpu/drm/vc4/vc4_drv.h:9,
from drivers/gpu/drm/vc4/vc4_bo.c:21:
>> arch/m68k/include/asm/uaccess_mm.h:368:2: warning: passing argument 2 of '__constant_copy_from_user' makes pointer from integer without a cast
__constant_copy_from_user(to, from, n) : \
^
>> arch/m68k/include/asm/uaccess_mm.h:379:37: note: in expansion of macro '__copy_from_user'
#define copy_from_user(to, from, n) __copy_from_user(to, from, n)
^
drivers/gpu/drm/vc4/vc4_bo.c:502:6: note: in expansion of macro 'copy_from_user'
if (copy_from_user(bo->base.vaddr,
^
arch/m68k/include/asm/uaccess_mm.h:239:1: note: expected 'const void *' but argument is of type 'int'
__constant_copy_from_user(void *to, const void __user *from, unsigned long n)
^
>> arch/m68k/include/asm/uaccess_mm.h:369:2: warning: passing argument 2 of '__generic_copy_from_user' makes pointer from integer without a cast
__generic_copy_from_user(to, from, n))
^
>> arch/m68k/include/asm/uaccess_mm.h:379:37: note: in expansion of macro '__copy_from_user'
#define copy_from_user(to, from, n) __copy_from_user(to, from, n)
^
drivers/gpu/drm/vc4/vc4_bo.c:502:6: note: in expansion of macro 'copy_from_user'
if (copy_from_user(bo->base.vaddr,
^
arch/m68k/include/asm/uaccess_mm.h:202:15: note: expected 'const void *' but argument is of type 'int'
unsigned long __generic_copy_from_user(void *to, const void __user *from, unsigned long n);
^
cc1: some warnings being treated as errors
--
drivers/gpu/drm/vc4/vc4_gem.c: In function 'vc4_get_hang_state_ioctl':
drivers/gpu/drm/vc4/vc4_gem.c:123:2: error: implicit declaration of function 'u64_to_user_ptr' [-Werror=implicit-function-declaration]
if (copy_to_user(u64_to_user_ptr(get_state->bo),
^
In file included from arch/m68k/include/asm/uaccess.h:4:0,
from include/linux/uaccess.h:5,
from include/linux/highmem.h:8,
from include/drm/drmP.h:40,
from drivers/gpu/drm/vc4/vc4_drv.h:9,
from drivers/gpu/drm/vc4/vc4_gem.c:31:
>> arch/m68k/include/asm/uaccess_mm.h:373:2: warning: passing argument 1 of '__constant_copy_to_user' makes pointer from integer without a cast
__constant_copy_to_user(to, from, n) : \
^
>> arch/m68k/include/asm/uaccess_mm.h:380:35: note: in expansion of macro '__copy_to_user'
#define copy_to_user(to, from, n) __copy_to_user(to, from, n)
^
drivers/gpu/drm/vc4/vc4_gem.c:123:6: note: in expansion of macro 'copy_to_user'
if (copy_to_user(u64_to_user_ptr(get_state->bo),
^
arch/m68k/include/asm/uaccess_mm.h:320:1: note: expected 'void *' but argument is of type 'int'
__constant_copy_to_user(void __user *to, const void *from, unsigned long n)
^
>> arch/m68k/include/asm/uaccess_mm.h:374:2: warning: passing argument 1 of '__generic_copy_to_user' makes pointer from integer without a cast
__generic_copy_to_user(to, from, n))
^
>> arch/m68k/include/asm/uaccess_mm.h:380:35: note: in expansion of macro '__copy_to_user'
#define copy_to_user(to, from, n) __copy_to_user(to, from, n)
^
drivers/gpu/drm/vc4/vc4_gem.c:123:6: note: in expansion of macro 'copy_to_user'
if (copy_to_user(u64_to_user_ptr(get_state->bo),
^
arch/m68k/include/asm/uaccess_mm.h:203:15: note: expected 'void *' but argument is of type 'int'
unsigned long __generic_copy_to_user(void __user *to, const void *from, unsigned long n);
^
drivers/gpu/drm/vc4/vc4_gem.c: In function 'vc4_cl_lookup_bos':
>> arch/m68k/include/asm/uaccess_mm.h:368:2: warning: passing argument 2 of '__constant_copy_from_user' makes pointer from integer without a cast
__constant_copy_from_user(to, from, n) : \
^
>> arch/m68k/include/asm/uaccess_mm.h:379:37: note: in expansion of macro '__copy_from_user'
#define copy_from_user(to, from, n) __copy_from_user(to, from, n)
^
drivers/gpu/drm/vc4/vc4_gem.c:552:8: note: in expansion of macro 'copy_from_user'
ret = copy_from_user(handles,
^
arch/m68k/include/asm/uaccess_mm.h:239:1: note: expected 'const void *' but argument is of type 'int'
__constant_copy_from_user(void *to, const void __user *from, unsigned long n)
^
>> arch/m68k/include/asm/uaccess_mm.h:369:2: warning: passing argument 2 of '__generic_copy_from_user' makes pointer from integer without a cast
__generic_copy_from_user(to, from, n))
^
>> arch/m68k/include/asm/uaccess_mm.h:379:37: note: in expansion of macro '__copy_from_user'
#define copy_from_user(to, from, n) __copy_from_user(to, from, n)
^
drivers/gpu/drm/vc4/vc4_gem.c:552:8: note: in expansion of macro 'copy_from_user'
ret = copy_from_user(handles,
^
arch/m68k/include/asm/uaccess_mm.h:202:15: note: expected 'const void *' but argument is of type 'int'
unsigned long __generic_copy_from_user(void *to, const void __user *from, unsigned long n);
^
drivers/gpu/drm/vc4/vc4_gem.c: In function 'vc4_get_bcl':
>> arch/m68k/include/asm/uaccess_mm.h:368:2: warning: passing argument 2 of '__constant_copy_from_user' makes pointer from integer without a cast
__constant_copy_from_user(to, from, n) : \
^
>> arch/m68k/include/asm/uaccess_mm.h:379:37: note: in expansion of macro '__copy_from_user'
#define copy_from_user(to, from, n) __copy_from_user(to, from, n)
^
drivers/gpu/drm/vc4/vc4_gem.c:626:6: note: in expansion of macro 'copy_from_user'
if (copy_from_user(bin,
^
arch/m68k/include/asm/uaccess_mm.h:239:1: note: expected 'const void *' but argument is of type 'int'
__constant_copy_from_user(void *to, const void __user *from, unsigned long n)
^
>> arch/m68k/include/asm/uaccess_mm.h:369:2: warning: passing argument 2 of '__generic_copy_from_user' makes pointer from integer without a cast
__generic_copy_from_user(to, from, n))
^
>> arch/m68k/include/asm/uaccess_mm.h:379:37: note: in expansion of macro '__copy_from_user'
#define copy_from_user(to, from, n) __copy_from_user(to, from, n)
^
drivers/gpu/drm/vc4/vc4_gem.c:626:6: note: in expansion of macro 'copy_from_user'
if (copy_from_user(bin,
^
arch/m68k/include/asm/uaccess_mm.h:202:15: note: expected 'const void *' but argument is of type 'int'
unsigned long __generic_copy_from_user(void *to, const void __user *from, unsigned long n);
^
>> arch/m68k/include/asm/uaccess_mm.h:368:2: warning: passing argument 2 of '__constant_copy_from_user' makes pointer from integer without a cast
__constant_copy_from_user(to, from, n) : \
^
>> arch/m68k/include/asm/uaccess_mm.h:379:37: note: in expansion of macro '__copy_from_user'
#define copy_from_user(to, from, n) __copy_from_user(to, from, n)
^
drivers/gpu/drm/vc4/vc4_gem.c:633:6: note: in expansion of macro 'copy_from_user'
if (copy_from_user(exec->shader_rec_u,
^
arch/m68k/include/asm/uaccess_mm.h:239:1: note: expected 'const void *' but argument is of type 'int'
__constant_copy_from_user(void *to, const void __user *from, unsigned long n)
^
>> arch/m68k/include/asm/uaccess_mm.h:369:2: warning: passing argument 2 of '__generic_copy_from_user' makes pointer from integer without a cast
__generic_copy_from_user(to, from, n))
^
>> arch/m68k/include/asm/uaccess_mm.h:379:37: note: in expansion of macro '__copy_from_user'
#define copy_from_user(to, from, n) __copy_from_user(to, from, n)
^
drivers/gpu/drm/vc4/vc4_gem.c:633:6: note: in expansion of macro 'copy_from_user'
if (copy_from_user(exec->shader_rec_u,
^
arch/m68k/include/asm/uaccess_mm.h:202:15: note: expected 'const void *' but argument is of type 'int'
unsigned long __generic_copy_from_user(void *to, const void __user *from, unsigned long n);
^
>> arch/m68k/include/asm/uaccess_mm.h:368:2: warning: passing argument 2 of '__constant_copy_from_user' makes pointer from integer without a cast
__constant_copy_from_user(to, from, n) : \
^
>> arch/m68k/include/asm/uaccess_mm.h:379:37: note: in expansion of macro '__copy_from_user'
#define copy_from_user(to, from, n) __copy_from_user(to, from, n)
^
drivers/gpu/drm/vc4/vc4_gem.c:640:6: note: in expansion of macro 'copy_from_user'
if (copy_from_user(exec->uniforms_u,
^
arch/m68k/include/asm/uaccess_mm.h:239:1: note: expected 'const void *' but argument is of type 'int'
__constant_copy_from_user(void *to, const void __user *from, unsigned long n)
^
>> arch/m68k/include/asm/uaccess_mm.h:369:2: warning: passing argument 2 of '__generic_copy_from_user' makes pointer from integer without a cast
__generic_copy_from_user(to, from, n))
^
>> arch/m68k/include/asm/uaccess_mm.h:379:37: note: in expansion of macro '__copy_from_user'
#define copy_from_user(to, from, n) __copy_from_user(to, from, n)
^
drivers/gpu/drm/vc4/vc4_gem.c:640:6: note: in expansion of macro 'copy_from_user'
if (copy_from_user(exec->uniforms_u,
^
arch/m68k/include/asm/uaccess_mm.h:202:15: note: expected 'const void *' but argument is of type 'int'
unsigned long __generic_copy_from_user(void *to, const void __user *from, unsigned long n);
^
cc1: some warnings being treated as errors
vim +/__constant_copy_from_user +368 arch/m68k/include/asm/uaccess_mm.h
^1da177e include/asm-m68k/uaccess.h Linus Torvalds 2005-04-16 197 } \
^1da177e include/asm-m68k/uaccess.h Linus Torvalds 2005-04-16 198 __gu_err; \
^1da177e include/asm-m68k/uaccess.h Linus Torvalds 2005-04-16 199 })
d94af931 include/asm-m68k/uaccess.h Roman Zippel 2006-06-23 200 #define get_user(x, ptr) __get_user(x, ptr)
^1da177e include/asm-m68k/uaccess.h Linus Torvalds 2005-04-16 201
d94af931 include/asm-m68k/uaccess.h Roman Zippel 2006-06-23 202 unsigned long __generic_copy_from_user(void *to, const void __user *from, unsigned long n);
d94af931 include/asm-m68k/uaccess.h Roman Zippel 2006-06-23 @203 unsigned long __generic_copy_to_user(void __user *to, const void *from, unsigned long n);
^1da177e include/asm-m68k/uaccess.h Linus Torvalds 2005-04-16 204
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 205 #define __constant_copy_from_user_asm(res, to, from, tmp, n, s1, s2, s3)\
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 206 asm volatile ("\n" \
e08d703c arch/m68k/include/asm/uaccess_mm.h Greg Ungerer 2011-10-14 207 "1: "MOVES"."#s1" (%2)+,%3\n" \
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 208 " move."#s1" %3,(%1)+\n" \
e08d703c arch/m68k/include/asm/uaccess_mm.h Greg Ungerer 2011-10-14 209 "2: "MOVES"."#s2" (%2)+,%3\n" \
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 210 " move."#s2" %3,(%1)+\n" \
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 211 " .ifnc \""#s3"\",\"\"\n" \
e08d703c arch/m68k/include/asm/uaccess_mm.h Greg Ungerer 2011-10-14 212 "3: "MOVES"."#s3" (%2)+,%3\n" \
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 213 " move."#s3" %3,(%1)+\n" \
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 214 " .endif\n" \
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 215 "4:\n" \
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 216 " .section __ex_table,\"a\"\n" \
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 217 " .align 4\n" \
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 218 " .long 1b,10f\n" \
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 219 " .long 2b,20f\n" \
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 220 " .ifnc \""#s3"\",\"\"\n" \
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 221 " .long 3b,30f\n" \
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 222 " .endif\n" \
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 223 " .previous\n" \
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 224 "\n" \
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 225 " .section .fixup,\"ax\"\n" \
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 226 " .even\n" \
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 227 "10: clr."#s1" (%1)+\n" \
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 228 "20: clr."#s2" (%1)+\n" \
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 229 " .ifnc \""#s3"\",\"\"\n" \
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 230 "30: clr."#s3" (%1)+\n" \
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 231 " .endif\n" \
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 232 " moveq.l #"#n",%0\n" \
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 233 " jra 4b\n" \
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 234 " .previous\n" \
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 235 : "+d" (res), "+&a" (to), "+a" (from), "=&d" (tmp) \
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 236 : : "memory")
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 237
d94af931 include/asm-m68k/uaccess.h Roman Zippel 2006-06-23 238 static __always_inline unsigned long
d94af931 include/asm-m68k/uaccess.h Roman Zippel 2006-06-23 239 __constant_copy_from_user(void *to, const void __user *from, unsigned long n)
^1da177e include/asm-m68k/uaccess.h Linus Torvalds 2005-04-16 240 {
d94af931 include/asm-m68k/uaccess.h Roman Zippel 2006-06-23 241 unsigned long res = 0, tmp;
^1da177e include/asm-m68k/uaccess.h Linus Torvalds 2005-04-16 242
^1da177e include/asm-m68k/uaccess.h Linus Torvalds 2005-04-16 243 switch (n) {
^1da177e include/asm-m68k/uaccess.h Linus Torvalds 2005-04-16 244 case 1:
b971018b include/asm-m68k/uaccess.h Al Viro 2006-10-11 245 __get_user_asm(res, *(u8 *)to, (u8 __user *)from, u8, b, d, 1);
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 246 break;
^1da177e include/asm-m68k/uaccess.h Linus Torvalds 2005-04-16 247 case 2:
631d8b67 arch/m68k/include/asm/uaccess_mm.h Geert Uytterhoeven 2013-06-09 248 __get_user_asm(res, *(u16 *)to, (u16 __user *)from, u16, w, r, 2);
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 249 break;
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 250 case 3:
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 251 __constant_copy_from_user_asm(res, to, from, tmp, 3, w, b,);
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 252 break;
^1da177e include/asm-m68k/uaccess.h Linus Torvalds 2005-04-16 253 case 4:
b971018b include/asm-m68k/uaccess.h Al Viro 2006-10-11 254 __get_user_asm(res, *(u32 *)to, (u32 __user *)from, u32, l, r, 4);
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 255 break;
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 256 case 5:
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 257 __constant_copy_from_user_asm(res, to, from, tmp, 5, l, b,);
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 258 break;
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 259 case 6:
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 260 __constant_copy_from_user_asm(res, to, from, tmp, 6, l, w,);
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 261 break;
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 262 case 7:
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 263 __constant_copy_from_user_asm(res, to, from, tmp, 7, l, w, b);
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 264 break;
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 265 case 8:
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 266 __constant_copy_from_user_asm(res, to, from, tmp, 8, l, l,);
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 267 break;
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 268 case 9:
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 269 __constant_copy_from_user_asm(res, to, from, tmp, 9, l, l, b);
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 270 break;
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 271 case 10:
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 272 __constant_copy_from_user_asm(res, to, from, tmp, 10, l, l, w);
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 273 break;
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 274 case 12:
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 275 __constant_copy_from_user_asm(res, to, from, tmp, 12, l, l, l);
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 276 break;
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 277 default:
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 278 /* we limit the inlined version to 3 moves */
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 279 return __generic_copy_from_user(to, from, n);
d94af931 include/asm-m68k/uaccess.h Roman Zippel 2006-06-23 280 }
d94af931 include/asm-m68k/uaccess.h Roman Zippel 2006-06-23 281
d94af931 include/asm-m68k/uaccess.h Roman Zippel 2006-06-23 282 return res;
d94af931 include/asm-m68k/uaccess.h Roman Zippel 2006-06-23 283 }
^1da177e include/asm-m68k/uaccess.h Linus Torvalds 2005-04-16 284
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 285 #define __constant_copy_to_user_asm(res, to, from, tmp, n, s1, s2, s3) \
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 286 asm volatile ("\n" \
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 287 " move."#s1" (%2)+,%3\n" \
e08d703c arch/m68k/include/asm/uaccess_mm.h Greg Ungerer 2011-10-14 288 "11: "MOVES"."#s1" %3,(%1)+\n" \
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 289 "12: move."#s2" (%2)+,%3\n" \
e08d703c arch/m68k/include/asm/uaccess_mm.h Greg Ungerer 2011-10-14 290 "21: "MOVES"."#s2" %3,(%1)+\n" \
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 291 "22:\n" \
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 292 " .ifnc \""#s3"\",\"\"\n" \
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 293 " move."#s3" (%2)+,%3\n" \
e08d703c arch/m68k/include/asm/uaccess_mm.h Greg Ungerer 2011-10-14 294 "31: "MOVES"."#s3" %3,(%1)+\n" \
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 295 "32:\n" \
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 296 " .endif\n" \
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 297 "4:\n" \
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 298 "\n" \
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 299 " .section __ex_table,\"a\"\n" \
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 300 " .align 4\n" \
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 301 " .long 11b,5f\n" \
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 302 " .long 12b,5f\n" \
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 303 " .long 21b,5f\n" \
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 304 " .long 22b,5f\n" \
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 305 " .ifnc \""#s3"\",\"\"\n" \
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 306 " .long 31b,5f\n" \
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 307 " .long 32b,5f\n" \
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 308 " .endif\n" \
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 309 " .previous\n" \
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 310 "\n" \
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 311 " .section .fixup,\"ax\"\n" \
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 312 " .even\n" \
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 313 "5: moveq.l #"#n",%0\n" \
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 314 " jra 4b\n" \
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 315 " .previous\n" \
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 316 : "+d" (res), "+a" (to), "+a" (from), "=&d" (tmp) \
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 317 : : "memory")
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 318
d94af931 include/asm-m68k/uaccess.h Roman Zippel 2006-06-23 319 static __always_inline unsigned long
11c40f8a include/asm-m68k/uaccess.h Al Viro 2006-01-12 320 __constant_copy_to_user(void __user *to, const void *from, unsigned long n)
^1da177e include/asm-m68k/uaccess.h Linus Torvalds 2005-04-16 321 {
d94af931 include/asm-m68k/uaccess.h Roman Zippel 2006-06-23 322 unsigned long res = 0, tmp;
d94af931 include/asm-m68k/uaccess.h Roman Zippel 2006-06-23 323
^1da177e include/asm-m68k/uaccess.h Linus Torvalds 2005-04-16 324 switch (n) {
^1da177e include/asm-m68k/uaccess.h Linus Torvalds 2005-04-16 325 case 1:
b971018b include/asm-m68k/uaccess.h Al Viro 2006-10-11 326 __put_user_asm(res, *(u8 *)from, (u8 __user *)to, b, d, 1);
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 327 break;
^1da177e include/asm-m68k/uaccess.h Linus Torvalds 2005-04-16 328 case 2:
631d8b67 arch/m68k/include/asm/uaccess_mm.h Geert Uytterhoeven 2013-06-09 329 __put_user_asm(res, *(u16 *)from, (u16 __user *)to, w, r, 2);
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 330 break;
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 331 case 3:
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 332 __constant_copy_to_user_asm(res, to, from, tmp, 3, w, b,);
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 333 break;
^1da177e include/asm-m68k/uaccess.h Linus Torvalds 2005-04-16 334 case 4:
b971018b include/asm-m68k/uaccess.h Al Viro 2006-10-11 335 __put_user_asm(res, *(u32 *)from, (u32 __user *)to, l, r, 4);
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 336 break;
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 337 case 5:
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 338 __constant_copy_to_user_asm(res, to, from, tmp, 5, l, b,);
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 339 break;
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 340 case 6:
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 341 __constant_copy_to_user_asm(res, to, from, tmp, 6, l, w,);
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 342 break;
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 343 case 7:
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 344 __constant_copy_to_user_asm(res, to, from, tmp, 7, l, w, b);
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 345 break;
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 346 case 8:
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 347 __constant_copy_to_user_asm(res, to, from, tmp, 8, l, l,);
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 348 break;
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 349 case 9:
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 350 __constant_copy_to_user_asm(res, to, from, tmp, 9, l, l, b);
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 351 break;
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 352 case 10:
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 353 __constant_copy_to_user_asm(res, to, from, tmp, 10, l, l, w);
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 354 break;
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 355 case 12:
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 356 __constant_copy_to_user_asm(res, to, from, tmp, 12, l, l, l);
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 357 break;
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 358 default:
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 359 /* limit the inlined version to 3 moves */
53617825 include/asm-m68k/uaccess.h Roman Zippel 2006-06-25 360 return __generic_copy_to_user(to, from, n);
d94af931 include/asm-m68k/uaccess.h Roman Zippel 2006-06-23 361 }
d94af931 include/asm-m68k/uaccess.h Roman Zippel 2006-06-23 362
d94af931 include/asm-m68k/uaccess.h Roman Zippel 2006-06-23 363 return res;
^1da177e include/asm-m68k/uaccess.h Linus Torvalds 2005-04-16 364 }
^1da177e include/asm-m68k/uaccess.h Linus Torvalds 2005-04-16 365
d94af931 include/asm-m68k/uaccess.h Roman Zippel 2006-06-23 366 #define __copy_from_user(to, from, n) \
^1da177e include/asm-m68k/uaccess.h Linus Torvalds 2005-04-16 367 (__builtin_constant_p(n) ? \
^1da177e include/asm-m68k/uaccess.h Linus Torvalds 2005-04-16 @368 __constant_copy_from_user(to, from, n) : \
^1da177e include/asm-m68k/uaccess.h Linus Torvalds 2005-04-16 @369 __generic_copy_from_user(to, from, n))
^1da177e include/asm-m68k/uaccess.h Linus Torvalds 2005-04-16 370
d94af931 include/asm-m68k/uaccess.h Roman Zippel 2006-06-23 371 #define __copy_to_user(to, from, n) \
^1da177e include/asm-m68k/uaccess.h Linus Torvalds 2005-04-16 372 (__builtin_constant_p(n) ? \
^1da177e include/asm-m68k/uaccess.h Linus Torvalds 2005-04-16 @373 __constant_copy_to_user(to, from, n) : \
^1da177e include/asm-m68k/uaccess.h Linus Torvalds 2005-04-16 @374 __generic_copy_to_user(to, from, n))
^1da177e include/asm-m68k/uaccess.h Linus Torvalds 2005-04-16 375
d94af931 include/asm-m68k/uaccess.h Roman Zippel 2006-06-23 376 #define __copy_to_user_inatomic __copy_to_user
d94af931 include/asm-m68k/uaccess.h Roman Zippel 2006-06-23 377 #define __copy_from_user_inatomic __copy_from_user
^1da177e include/asm-m68k/uaccess.h Linus Torvalds 2005-04-16 378
d94af931 include/asm-m68k/uaccess.h Roman Zippel 2006-06-23 @379 #define copy_from_user(to, from, n) __copy_from_user(to, from, n)
d94af931 include/asm-m68k/uaccess.h Roman Zippel 2006-06-23 @380 #define copy_to_user(to, from, n) __copy_to_user(to, from, n)
^1da177e include/asm-m68k/uaccess.h Linus Torvalds 2005-04-16 381
d8ce7263 arch/m68k/include/asm/uaccess_mm.h Geert Uytterhoeven 2012-05-29 382 #define user_addr_max() \
d8ce7263 arch/m68k/include/asm/uaccess_mm.h Geert Uytterhoeven 2012-05-29 383 (segment_eq(get_fs(), USER_DS) ? TASK_SIZE : ~0UL)
:::::: The code at line 368 was first introduced by commit
:::::: 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 Linux-2.6.12-rc2
:::::: TO: Linus Torvalds <torvalds@ppc970.osdl.org>
:::::: CC: Linus Torvalds <torvalds@ppc970.osdl.org>
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 35362 bytes --]
[-- Attachment #3: Type: text/plain, Size: 183 bytes --]
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
^ permalink raw reply
* [PATCH] gpu/drm: Use u64_to_user_pointer
From: Joe Perches @ 2016-03-18 17:20 UTC (permalink / raw)
To: Gustavo Padovan, Russell King, Thierry Reding,
Terje Bergström, Stephen Warren, Alexandre Courbot,
David Airlie, Gerd Hoffmann
Cc: Greg Kroah-Hartman, linux-kernel, dri-devel, virtualization,
Rob Clark, linux-tegra, Daniel Vetter, Andrew Morton
In-Reply-To: <1458315564.9556.56.camel@perches.com>
Use the newly added u64_to_user_pointer a bit more frequently.
Signed-off-by: Joe Perches <joe@perches.com>
---
drivers/gpu/drm/armada/armada_gem.c | 2 +-
drivers/gpu/drm/nouveau/nouveau_gem.c | 7 ++++---
drivers/gpu/drm/tegra/drm.c | 15 ++++++++-------
drivers/gpu/drm/vc4/vc4_bo.c | 4 ++--
drivers/gpu/drm/vc4/vc4_gem.c | 10 +++++-----
drivers/gpu/drm/virtio/virtgpu_ioctl.c | 5 ++---
6 files changed, 22 insertions(+), 21 deletions(-)
diff --git a/drivers/gpu/drm/armada/armada_gem.c b/drivers/gpu/drm/armada/armada_gem.c
index 6e731db..7629dd2 100644
--- a/drivers/gpu/drm/armada/armada_gem.c
+++ b/drivers/gpu/drm/armada/armada_gem.c
@@ -382,7 +382,7 @@ int armada_gem_pwrite_ioctl(struct drm_device *dev, void *data,
if (args->size == 0)
return 0;
- ptr = (char __user *)(uintptr_t)args->ptr;
+ ptr = u64_to_user_ptr(args->ptr);
if (!access_ok(VERIFY_READ, ptr, args->size))
return -EFAULT;
diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c
index a0865c4..1a6604c9 100644
--- a/drivers/gpu/drm/nouveau/nouveau_gem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
@@ -467,11 +467,12 @@ validate_list(struct nouveau_channel *chan, struct nouveau_cli *cli,
uint64_t user_pbbo_ptr)
{
struct nouveau_drm *drm = chan->drm;
- struct drm_nouveau_gem_pushbuf_bo __user *upbbo =
- (void __force __user *)(uintptr_t)user_pbbo_ptr;
+ struct drm_nouveau_gem_pushbuf_bo __user *upbbo;
struct nouveau_bo *nvbo;
int ret, relocs = 0;
+ upbbo = u64_to_user_ptr(user_pbbo_ptr);
+
list_for_each_entry(nvbo, list, entry) {
struct drm_nouveau_gem_pushbuf_bo *b = &pbbo[nvbo->pbbo_index];
@@ -565,7 +566,7 @@ static inline void *
u_memcpya(uint64_t user, unsigned nmemb, unsigned size)
{
void *mem;
- void __user *userptr = (void __force __user *)(uintptr_t)user;
+ void __user *userptr = u64_to_user_ptr(user);
size *= nmemb;
diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c
index 8e6b18c..b20c87d 100644
--- a/drivers/gpu/drm/tegra/drm.c
+++ b/drivers/gpu/drm/tegra/drm.c
@@ -329,12 +329,9 @@ int tegra_drm_submit(struct tegra_drm_context *context,
unsigned int num_cmdbufs = args->num_cmdbufs;
unsigned int num_relocs = args->num_relocs;
unsigned int num_waitchks = args->num_waitchks;
- struct drm_tegra_cmdbuf __user *cmdbufs =
- (void __user *)(uintptr_t)args->cmdbufs;
- struct drm_tegra_reloc __user *relocs =
- (void __user *)(uintptr_t)args->relocs;
- struct drm_tegra_waitchk __user *waitchks =
- (void __user *)(uintptr_t)args->waitchks;
+ struct drm_tegra_cmdbuf __user *cmdbufs;
+ struct drm_tegra_reloc __user *relocs;
+ struct drm_tegra_waitchk __user *waitchks;
struct drm_tegra_syncpt syncpt;
struct host1x_job *job;
int err;
@@ -354,6 +351,10 @@ int tegra_drm_submit(struct tegra_drm_context *context,
job->class = context->client->base.class;
job->serialize = true;
+ cmdbufs = u64_to_user_ptr(args->cmdbufs);
+ relocs = u64_to_user_ptr(args->relocs);
+ waitchks = u64_to_user_ptr(args->waitchks);
+
while (num_cmdbufs) {
struct drm_tegra_cmdbuf cmdbuf;
struct host1x_bo *bo;
@@ -389,7 +390,7 @@ int tegra_drm_submit(struct tegra_drm_context *context,
goto fail;
}
- if (copy_from_user(&syncpt, (void __user *)(uintptr_t)args->syncpts,
+ if (copy_from_user(&syncpt, u64_to_user_ptr(args->syncpts),
sizeof(syncpt))) {
err = -EFAULT;
goto fail;
diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c
index 9807bc9..fe3a4aa 100644
--- a/drivers/gpu/drm/vc4/vc4_bo.c
+++ b/drivers/gpu/drm/vc4/vc4_bo.c
@@ -499,8 +499,8 @@ vc4_create_shader_bo_ioctl(struct drm_device *dev, void *data,
return PTR_ERR(bo);
if (copy_from_user(bo->base.vaddr,
- (void __user *)(uintptr_t)args->data,
- args->size)) {
+ u64_to_user_ptr(args->data),
+ args->size)) {
ret = -EFAULT;
goto fail;
}
diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c
index 8d4384f..89d7931 100644
--- a/drivers/gpu/drm/vc4/vc4_gem.c
+++ b/drivers/gpu/drm/vc4/vc4_gem.c
@@ -120,7 +120,7 @@ vc4_get_hang_state_ioctl(struct drm_device *dev, void *data,
bo_state[i].size = vc4_bo->base.base.size;
}
- if (copy_to_user((void __user *)(uintptr_t)get_state->bo,
+ if (copy_to_user(u64_to_user_ptr(get_state->bo),
bo_state,
state->bo_count * sizeof(*bo_state)))
ret = -EFAULT;
@@ -550,7 +550,7 @@ vc4_cl_lookup_bos(struct drm_device *dev,
}
ret = copy_from_user(handles,
- (void __user *)(uintptr_t)args->bo_handles,
+ u64_to_user_ptr(args->bo_handles),
exec->bo_count * sizeof(uint32_t));
if (ret) {
DRM_ERROR("Failed to copy in GEM handles\n");
@@ -624,21 +624,21 @@ vc4_get_bcl(struct drm_device *dev, struct vc4_exec_info *exec)
exec->shader_state_size = args->shader_rec_count;
if (copy_from_user(bin,
- (void __user *)(uintptr_t)args->bin_cl,
+ u64_to_user_ptr(args->bin_cl),
args->bin_cl_size)) {
ret = -EFAULT;
goto fail;
}
if (copy_from_user(exec->shader_rec_u,
- (void __user *)(uintptr_t)args->shader_rec,
+ u64_to_user_ptr(args->shader_rec),
args->shader_rec_size)) {
ret = -EFAULT;
goto fail;
}
if (copy_from_user(exec->uniforms_u,
- (void __user *)(uintptr_t)args->uniforms,
+ u64_to_user_ptr(args->uniforms),
args->uniforms_size)) {
ret = -EFAULT;
goto fail;
diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
index b4de18e..e602bb6 100644
--- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c
+++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
@@ -123,7 +123,7 @@ static int virtio_gpu_execbuffer(struct drm_device *dev,
return -ENOMEM;
}
- user_bo_handles = (void __user *)(uintptr_t)exbuf->bo_handles;
+ user_bo_handles = u64_to_user_ptr(exbuf->bo_handles);
if (copy_from_user(bo_handles, user_bo_handles,
exbuf->num_bo_handles * sizeof(uint32_t))) {
ret = -EFAULT;
@@ -158,8 +158,7 @@ static int virtio_gpu_execbuffer(struct drm_device *dev,
ret = -ENOMEM;
goto out_unresv;
}
- if (copy_from_user(buf, (void __user *)(uintptr_t)exbuf->command,
- exbuf->size)) {
+ if (copy_from_user(buf, u64_to_user_ptr(exbuf->command), exbuf->size)) {
kfree(buf);
ret = -EFAULT;
goto out_unresv;
--
2.6.3.368.gf34be46
^ permalink raw reply related
* Re: [net-next v2] virtio_net: replace netdev_alloc_skb_ip_align() with napi_alloc_skb()
From: Venkatesh Srinivas via Virtualization @ 2016-03-18 15:58 UTC (permalink / raw)
To: Paolo Abeni
Cc: netdev, virtualization, Hannes Frederic Sowa, Michael S. Tsirkin
In-Reply-To: <98c94ca899603eb4212c44aa1a658825198ed49a.1458290241.git.pabeni@redhat.com>
On Fri, Mar 18, 2016 at 8:42 AM, Paolo Abeni <pabeni@redhat.com> wrote:
> This gives small but noticeable rx performance improvement (2-3%)
> and will allow exploiting future napi improvement.
>
> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
>
> --
> v2: replace also netdev_alloc_skb_ip_align() invocation in
> add_recvbuf_small(), suggested by Venkatesh Srinivas
> ---
> drivers/net/virtio_net.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> index fb0eae4..100e039 100644
> --- a/drivers/net/virtio_net.c
> +++ b/drivers/net/virtio_net.c
> @@ -260,7 +260,7 @@ static struct sk_buff *page_to_skb(struct virtnet_info *vi,
> p = page_address(page) + offset;
>
> /* copy small packet so we can reuse these pages for small data */
> - skb = netdev_alloc_skb_ip_align(vi->dev, GOOD_COPY_LEN);
> + skb = napi_alloc_skb(&rq->napi, GOOD_COPY_LEN);
> if (unlikely(!skb))
> return NULL;
>
> @@ -541,7 +541,7 @@ static int add_recvbuf_small(struct virtnet_info *vi, struct receive_queue *rq,
> struct virtio_net_hdr_mrg_rxbuf *hdr;
> int err;
>
> - skb = __netdev_alloc_skb_ip_align(vi->dev, GOOD_PACKET_LEN, gfp);
> + skb = __napi_alloc_skb(&rq->napi, GOOD_PACKET_LEN, gfp);
> if (unlikely(!skb))
> return -ENOMEM;
Sorry, I should've mentioned more in my first reply --
add_recvbuf_small is called from try_fill_recv in both
NAPI and non-NAPI context (NAPI: via virtnet_receive from
virtnet_poll; non-NAPI: via scheduled work,
via virtnet_probe, and via virtnet_restore).
I don't believe you can use __napi_alloc_skb() for the non-NAPI paths,
it'd be a bit more work to plumb
the context as an argument if you think its worth doing here.
Looking forward to bulk skb allocation either way.
HTH,
-- vs;
^ permalink raw reply
* [net-next v2] virtio_net: replace netdev_alloc_skb_ip_align() with napi_alloc_skb()
From: Paolo Abeni @ 2016-03-18 15:42 UTC (permalink / raw)
To: netdev; +Cc: virtualization, Hannes Frederic Sowa, Michael S. Tsirkin
This gives small but noticeable rx performance improvement (2-3%)
and will allow exploiting future napi improvement.
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
--
v2: replace also netdev_alloc_skb_ip_align() invocation in
add_recvbuf_small(), suggested by Venkatesh Srinivas
---
drivers/net/virtio_net.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index fb0eae4..100e039 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -260,7 +260,7 @@ static struct sk_buff *page_to_skb(struct virtnet_info *vi,
p = page_address(page) + offset;
/* copy small packet so we can reuse these pages for small data */
- skb = netdev_alloc_skb_ip_align(vi->dev, GOOD_COPY_LEN);
+ skb = napi_alloc_skb(&rq->napi, GOOD_COPY_LEN);
if (unlikely(!skb))
return NULL;
@@ -541,7 +541,7 @@ static int add_recvbuf_small(struct virtnet_info *vi, struct receive_queue *rq,
struct virtio_net_hdr_mrg_rxbuf *hdr;
int err;
- skb = __netdev_alloc_skb_ip_align(vi->dev, GOOD_PACKET_LEN, gfp);
+ skb = __napi_alloc_skb(&rq->napi, GOOD_PACKET_LEN, gfp);
if (unlikely(!skb))
return -ENOMEM;
--
1.8.3.1
^ permalink raw reply related
* CfP 11th Workshop on Virtualization in High-Performance Cloud Computing (VHPC '16)
From: VHPC 16 @ 2016-03-18 14:57 UTC (permalink / raw)
To: virtualization
[-- Attachment #1.1: Type: text/plain, Size: 8363 bytes --]
====================================================================
CALL FOR PAPERS
11th Workshop on Virtualization in High-Performance Cloud Computing (VHPC
'16)
held in conjunction with the International Supercomputing Conference - High
Performance,
June 19-23, 2016, Frankfurt, Germany.
====================================================================
Date: June 23, 2016
Workshop URL: http://vhpc.org
Paper Submission Deadline: April 25, 2016
Call for Papers
Virtualization technologies constitute a key enabling factor for flexible
resource
management in modern data centers, and particularly in cloud environments.
Cloud providers need to manage complex infrastructures in a seamless
fashion to support
the highly dynamic and heterogeneous workloads and hosted applications
customers
deploy. Similarly, HPC environments have been increasingly adopting
techniques that
enable flexible management of vast computing and networking resources,
close to marginal
provisioning cost, which is unprecedented in the history of scientific and
commercial
computing.
Various virtualization technologies contribute to the overall picture in
different ways: machine
virtualization, with its capability to enable consolidation of multiple
underutilized servers with
heterogeneous software and operating systems (OSes), and its capability to
live-migrate a
fully operating virtual machine (VM) with a very short downtime, enables
novel and dynamic
ways to manage physical servers; OS-level virtualization (i.e.,
containerization), with its
capability to isolate multiple user-space environments and to allow for
their coexistence
within the same OS kernel, promises to provide many of the advantages of
machine
virtualization with high levels of responsiveness and performance; I/O
Virtualization allows
physical NICs/HBAs to take traffic from multiple VMs or containers; network
virtualization,
with its capability to create logical network overlays that are independent
of the underlying
physical topology and IP addressing, provides the fundamental ground on top
of which
evolved network services can be realized with an unprecedented level of
dynamicity and
flexibility; the increasingly adopted paradigm of Software-Defined
Networking (SDN)
promises to extend this flexibility to the control and data planes of
network paths.
Topics of Interest
The VHPC program committee solicits original, high-quality submissions
related to
virtualization across the entire software stack with a special focus on the
intersection of HPC
and the cloud. Topics include, but are not limited to:
- Virtualization in supercomputing environments, HPC clusters, cloud HPC
and grids
- OS-level virtualization including container runtimes (Docker, rkt et al.)
- Lightweight compute node operating systems/VMMs
- Optimizations of virtual machine monitor platforms, hypervisors
- QoS and SLA in hypervisors and network virtualization
- Cloud based network and system management for SDN and NFV
- Management, deployment and monitoring of virtualized environments
- Virtual per job / on-demand clusters and cloud bursting
- Performance measurement, modelling and monitoring of virtualized/cloud
workloads
- Programming models for virtualized environments
- Virtualization in data intensive computing and Big Data processing
- Cloud reliability, fault-tolerance, high-availability and security
- Heterogeneous virtualized environments, virtualized accelerators, GPUs
and co-processors
- Optimized communication libraries/protocols in the cloud and for HPC in
the cloud
- Topology management and optimization for distributed virtualized
applications
- Adaptation of emerging HPC technologies (high performance networks, RDMA,
etc..)
- I/O and storage virtualization, virtualization aware file systems
- Job scheduling/control/policy in virtualized environments
- Checkpointing and migration of VM-based large compute jobs
- Cloud frameworks and APIs
- Energy-efficient / power-aware virtualization
The Workshop on Virtualization in High-Performance Cloud Computing (VHPC)
aims to
bring together researchers and industrial practitioners facing the
challenges
posed by virtualization in order to foster discussion, collaboration,
mutual exchange
of knowledge and experience, enabling research to ultimately provide novel
solutions for virtualized computing systems of tomorrow.
The workshop will be one day in length, composed of 20 min paper
presentations, each
followed by 10 min discussion sections, plus lightning talks that are
limited to 5 minutes.
Presentations may be accompanied by interactive demonstrations.
Important Dates
April 25, 2016 - Paper submission deadline
May 30, 2016 Acceptance notification
June 23, 2016 - Workshop Day
July 25, 2016 - Camera-ready version due
Chair
Michael Alexander (chair), TU Wien, Austria
Anastassios Nanos (co-chair), NTUA, Greece
Balazs Gerofi (co-chair), RIKEN Advanced Institute for Computational
Science, Japan
Program committee
Stergios Anastasiadis, University of Ioannina, Greece
Costas Bekas, IBM Research, Switzerland
Jakob Blomer, CERN
Ron Brightwell, Sandia National Laboratories, USA
Roberto Canonico, University of Napoli Federico II, Italy
Julian Chesterfield, OnApp, UK
Stephen Crago, USC ISI, USA
Christoffer Dall, Columbia University, USA
Patrick Dreher, MIT, USA
Robert Futrick, Cycle Computing, USA
Robert Gardner, University of Chicago, USA
William Gardner, University of Guelph, Canada
Wolfgang Gentzsch, UberCloud, USA
Kyle Hale, Northwestern University, USA
Marcus Hardt, Karlsruhe Institute of Technology, Germany
Krishna Kant, Templte University, USA
Romeo Kinzler, IBM, Switzerland
Brian Kocoloski, University of Pittsburgh, USA
Kornilios Kourtis, IBM Research, Switzerland
Nectarios Koziris, National Technical University of Athens, Greece
John Lange, University of Pittsburgh, USA
Nikos Parlavantzas, IRISA, France
Kevin Pendretti, Sandia National Laboratories, USA
Che-Rung Roger Lee, National Tsing Hua University, Taiwan
Giuseppe Lettieri, University of Pisa, Italy
Qing Liu, Oak Ridge National Laboratory, USA
Paul Mundt, Adaptant, Germany
Amer Qouneh, University of Florida, USA
Carlos Reaño, Technical University of Valencia, Spain
Seetharami Seelam, IBM Research, USA
Josh Simons, VMWare, USA
Borja Sotomayor, University of Chicago, USA
Dieter Suess, TU Wien, Austria
Craig Stewart, Indiana University, USA
Anata Tiwari, San Diego Supercomputer Center, USA
Kurt Tutschku, Blekinge Institute of Technology, Sweden
Amit Vadudevan, Carnegie Mellon University, USA
Yasuhiro Watashiba, Osaka University, Japan
Nicholas Wright, Lawrence Berkeley National Laboratory, USA
Chao-Tung Yang, Tunghai University, Taiwan
Gianluigi Zanetti, CRS4, Italy
Paper Submission-Publication
Papers submitted to the workshop will be reviewed by at least two
members of the program committee and external reviewers. Submissions
should include abstract, key words, the e-mail address of the
corresponding author, and must not exceed 10 pages, including tables
and figures at a main font size no smaller than 11 point. Submission
of a paper should be regarded as a commitment that, should the paper
be accepted, at least one of the authors will register and attend the
conference to present the work.
The format must be according to the Springer LNCS Style. Initial
submissions are in PDF; authors of accepted papers will be requested
to provide source files.
Format Guidelines:
ftp://ftp.springer.de/pub/tex/latex/llncs/latex2e/llncs2e.zip
Abstract, Paper Submission Link:
https://edas.info/newPaper.php?c=21801
Lightning Talks
Lightning Talks are non-paper track, synoptical in nature and are strictly
limited to 5 minutes.
They can be used to gain early feedback on ongoing research, for
demonstrations, to
present research results, early research ideas, perspectives and positions
of interest to the
community. Submit abstract via the main submission link.
General Information
The workshop is one day in length and will be held in conjunction with the
International
Supercomputing Conference - High Performance (ISC) 2016, June 19-23,
Frankfurt, Germany.
[-- Attachment #1.2: Type: text/html, Size: 10356 bytes --]
[-- Attachment #2: Type: text/plain, Size: 183 bytes --]
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
^ permalink raw reply
* Re: [PATCH net-next] virtio_net: replace netdev_alloc_skb_ip_align() with napi_alloc_skb()
From: Paolo Abeni @ 2016-03-18 8:21 UTC (permalink / raw)
To: Venkatesh Srinivas
Cc: netdev, Michael S. Tsirkin, Hannes Frederic Sowa, virtualization
In-Reply-To: <CAHdzE-_u35Kg1zck1KKCYhu5epx4vNtzE7UX41Bi85vsJ55ROw@mail.gmail.com>
On Thu, 2016-03-17 at 18:01 -0700, Venkatesh Srinivas wrote:
> On Thu, Mar 17, 2016 at 7:44 AM, Paolo Abeni <pabeni@redhat.com> wrote:
> >
> > This gives small but noticeable rx performance improvement (2-3%)
> > and will allow exploiting future napi improvement.
> >
> > Signed-off-by: Paolo Abeni <pabeni@redhat.com>
> > ---
>
> Worked in my tests, though the performance win was in the noise (+0.6%
> - +1% bandwidth).
> What tests did you see a 2-3% win on?
I'm doing net2VM tests (i.e. the traffic generator is on a different
host) with guest tuned a bit for performance. i.e. cpu pinning, no
iptables, no dhclient (yes, that makes a big difference:
http://lists.openwall.net/netdev/2013/10/29/5)
> Do you think its worth modifying add_recvbuf_small() to use
> napi_alloc_skb() when called from
> Rx NAPI (virtnet_receive)?
Oops, I missed that invocation. Probably that path is not hit in my
test. I think it should be really worthy.
I'll send a v2.
The important thing, more than the current improvement, is allowing the
virtio_net driver to leverage future napi allocation improvement (i.e.
bulk alloc: http://www.spinics.net/lists/netdev/msg367568.html) which
should be a real win.
Paolo
^ permalink raw reply
* Re: [PATCH net-next] virtio_net: replace netdev_alloc_skb_ip_align() with napi_alloc_skb()
From: Venkatesh Srinivas via Virtualization @ 2016-03-18 1:01 UTC (permalink / raw)
To: Paolo Abeni
Cc: netdev, Michael S. Tsirkin, Hannes Frederic Sowa, virtualization
In-Reply-To: <b436c3eb5d4c19e92184c27d89ec8118d6fd3f81.1458224603.git.pabeni@redhat.com>
On Thu, Mar 17, 2016 at 7:44 AM, Paolo Abeni <pabeni@redhat.com> wrote:
>
> This gives small but noticeable rx performance improvement (2-3%)
> and will allow exploiting future napi improvement.
>
> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
> ---
Worked in my tests, though the performance win was in the noise (+0.6%
- +1% bandwidth).
What tests did you see a 2-3% win on?
Do you think its worth modifying add_recvbuf_small() to use
napi_alloc_skb() when called from
Rx NAPI (virtnet_receive)?
Tested-by: Venkatesh Srinivas <venkateshs@google.com>
Thanks,
-- vs;
^ permalink raw reply
* Re: [PATCH net-next] virtio_net: replace netdev_alloc_skb_ip_align() with napi_alloc_skb()
From: Venkatesh Srinivas via Virtualization @ 2016-03-18 1:00 UTC (permalink / raw)
To: Paolo Abeni
Cc: netdev, Michael S. Tsirkin, Hannes Frederic Sowa, virtualization
In-Reply-To: <b436c3eb5d4c19e92184c27d89ec8118d6fd3f81.1458224603.git.pabeni@redhat.com>
[-- Attachment #1.1: Type: text/plain, Size: 568 bytes --]
On Thu, Mar 17, 2016 at 7:44 AM, Paolo Abeni <pabeni@redhat.com> wrote:
> This gives small but noticeable rx performance improvement (2-3%)
> and will allow exploiting future napi improvement.
>
> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
>
Worked in my tests, though the performance win was in the noise (+0.6% -
+1% bandwidth).
What tests did you see a 2-3% win on?
Do you think its worth modifying add_recvbuf_small() to use
napi_alloc_skb() when called from
Rx NAPI (virtnet_receive)?
Tested-by: Venkatesh Srinivas <venkateshs@google.com>
Thanks,
-- vs;
[-- Attachment #1.2: Type: text/html, Size: 1083 bytes --]
[-- Attachment #2: Type: text/plain, Size: 183 bytes --]
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
^ permalink raw reply
* Re: [PATCH v1 11/19] zsmalloc: squeeze freelist into page->mapping
From: Minchan Kim @ 2016-03-17 22:17 UTC (permalink / raw)
To: YiPing Xu
Cc: Rik van Riel, Sergey Senozhatsky, rknize, Sergey Senozhatsky,
Hugh Dickins, linux-kernel, virtualization, bfields, linux-mm,
Gioh Kim, Mel Gorman, koct9i, Joonsoo Kim, Andrew Morton, jlayton,
Vlastimil Babka, aquini
In-Reply-To: <56EA9E8E.5040206@hisilicon.com>
On Thu, Mar 17, 2016 at 08:09:50PM +0800, YiPing Xu wrote:
>
>
> On 2016/3/15 14:51, Minchan Kim wrote:
> >On Tue, Mar 15, 2016 at 03:40:53PM +0900, Sergey Senozhatsky wrote:
> >>On (03/11/16 16:30), Minchan Kim wrote:
> >>>-static void *location_to_obj(struct page *page, unsigned long obj_idx)
> >>>+static void objidx_to_page_and_ofs(struct size_class *class,
> >>>+ struct page *first_page,
> >>>+ unsigned long obj_idx,
> >>>+ struct page **obj_page,
> >>>+ unsigned long *ofs_in_page)
> >>
> >>this looks big; 5 params, function "returning" both page and offset...
> >>any chance to split it in two steps, perhaps?
> >
> >Yes, it's rather ugly but I don't have a good idea.
> >Feel free to suggest if you have a better idea.
> >
> >>
> >>besides, it is more intuitive (at least to me) when 'offset'
> >>shortened to 'offt', not 'ofs'.
>
> the purpose to get 'obj_page' and 'ofs_in_page' is to map the page
> and get the meta-data pointer in the page, so, we can finish this in
> a single function.
>
> just like this, and maybe we could have a better function name
>
> static unsigned long *map_handle(struct size_class *class,
> struct page *first_page, unsigned long obj_idx)
> {
> struct page *cursor = first_page;
> unsigned long offset = obj_idx * class->size;
> int nr_page = offset >> PAGE_SHIFT;
> unsigned long offset_in_page = offset & ~PAGE_MASK;
> void *addr;
> int i;
>
> if (class->huge) {
> VM_BUG_ON_PAGE(!is_first_page(page), page);
> return &page_private(page);
> }
>
> for (i = 0; i < nr_page; i++)
> cursor = get_next_page(cursor);
>
> addr = kmap_atomic(cursor);
>
> return addr + offset_in_page;
> }
>
> static void unmap_handle(unsigned long *addr)
> {
> if (class->huge) {
> return;
> }
>
> kunmap_atomic(addr & ~PAGE_MASK);
> }
>
> all functions called "objidx_to_page_and_ofs" could use it like
> this, for example:
>
> static unsigned long handle_from_obj(struct size_class *class,
> struct page *first_page, int obj_idx)
> {
> unsigned long *head = map_handle(class, first_page, obj_idx);
>
> if (*head & OBJ_ALLOCATED_TAG)
> handle = *head & ~OBJ_ALLOCATED_TAG;
>
> unmap_handle(*head);
>
> return handle;
> }
>
> 'freeze_zspage', u'nfreeze_zspage' use it in the same way.
>
> but in 'obj_malloc', we still have to get the page to get obj.
>
> obj = location_to_obj(m_page, obj);
Yes, That's why I didn't use such pattern. I didn't want to
add unnecessary overhead in that hot path.
^ permalink raw reply
* Re: [RFC v2 -next 1/2] virtio: Start feature MTU support
From: Stephen Hemminger @ 2016-03-17 22:04 UTC (permalink / raw)
To: Aaron Conole; +Cc: netdev, virtualization, linux-kernel, Michael S. Tsirkin
In-Reply-To: <f7tfuvox128.fsf@redhat.com>
On Thu, 17 Mar 2016 17:10:55 -0400
Aaron Conole <aconole@redhat.com> wrote:
> Stephen Hemminger <stephen@networkplumber.org> writes:
>
> > On Tue, 15 Mar 2016 17:04:12 -0400
> > Aaron Conole <aconole@redhat.com> wrote:
> >
> >> --- a/include/uapi/linux/virtio_net.h
> >> +++ b/include/uapi/linux/virtio_net.h
> >> @@ -55,6 +55,7 @@
> >> #define VIRTIO_NET_F_MQ 22 /* Device supports Receive Flow
> >> * Steering */
> >> #define VIRTIO_NET_F_CTRL_MAC_ADDR 23 /* Set MAC address */
> >> +#define VIRTIO_NET_F_MTU 25 /* Device supports Default MTU Negotiation */
> >>
> >> #ifndef VIRTIO_NET_NO_LEGACY
> >> #define VIRTIO_NET_F_GSO 6 /* Host handles pkts w/ any GSO type */
> >> @@ -73,6 +74,8 @@ struct virtio_net_config {
> >> * Legal values are between 1 and 0x8000
> >> */
> >> __u16 max_virtqueue_pairs;
> >> + /* Default maximum transmit unit advice */
> >> + __u16 mtu;
> >> } __attribute__((packed));
> >>
> >> /*
> >
> > You can't change user visible headers without breaking ABI.
> > This structure might be used by other user code. Also how can this
> > work if host is using old size of structure.
>
> How else can this field be added and remain compliant with the spec? The
> spec requires that mtu be passed in the virtio_net_config field.
>
> As for old sizeof, I think the absence of the VIRTIO_NET_F_MTU bit being
> asserted is confirmation that mtu is not valid (at least, it is implied
> in the spec).
Michael is right as long as the code checks for MTU flag before
referencing the mtu field, everything is fine. Actually, the structure
is never used directly only by fetching fields with offsetof
^ permalink raw reply
* Re: [RFC v2 -next 0/2] virtio-net: Advised MTU feature
From: Aaron Conole @ 2016-03-17 21:24 UTC (permalink / raw)
To: Pankaj Gupta; +Cc: netdev, virtualization, linux-kernel, Michael S. Tsirkin
In-Reply-To: <1969060351.30231176.1458104130844.JavaMail.zimbra@redhat.com>
Pankaj Gupta <pagupta@redhat.com> writes:
>>
>> The following series adds the ability for a hypervisor to set an MTU on the
>> guest during feature negotiation phase. This is useful for VM orchestration
>> when, for instance, tunneling is involved and the MTU of the various systems
>> should be homogenous.
>>
>> The first patch adds the feature bit as described in the proposed VFIO spec
>
> You mean VIRTIO spec?
Yes, sorry.
>> addition found at
>> https://lists.oasis-open.org/archives/virtio-dev/201603/msg00001.html
>>
>> The second patch adds a user of the bit, and a warning when the guest changes
>> the MTU from the hypervisor advised MTU. Future patches may add more thorough
>> error handling.
>>
>> v2:
>> * Whitespace and code style cleanups from Sergei Shtylyov and Paolo Abeni
>> * Additional test before printing a warning
>>
>> Aaron Conole (2):
>> virtio: Start feature MTU support
>> virtio_net: Read the advised MTU
>>
>> drivers/net/virtio_net.c | 12 ++++++++++++
>> include/uapi/linux/virtio_net.h | 3 +++
>> 2 files changed, 15 insertions(+)
>>
>> --
>> 2.5.0
>>
>>
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox