netvm: propagate page->pfmemalloc to skb
[profile/ivi/kernel-adaptation-intel-automotive.git] / include / linux / skbuff.h
index d205c4b..b814bb8 100644 (file)
@@ -462,6 +462,7 @@ struct sk_buff {
 #ifdef CONFIG_IPV6_NDISC_NODETYPE
        __u8                    ndisc_nodetype:2;
 #endif
+       __u8                    pfmemalloc:1;
        __u8                    ooo_okay:1;
        __u8                    l4_rxhash:1;
        __u8                    wifi_acked_valid:1;
@@ -502,6 +503,15 @@ struct sk_buff {
 #include <linux/slab.h>
 
 
+#define SKB_ALLOC_FCLONE       0x01
+#define SKB_ALLOC_RX           0x02
+
+/* Returns true if the skb was allocated from PFMEMALLOC reserves */
+static inline bool skb_pfmemalloc(const struct sk_buff *skb)
+{
+       return unlikely(skb->pfmemalloc);
+}
+
 /*
  * skb might have a dst pointer attached, refcounted or not.
  * _skb_refdst low order bit is set if refcount was _not_ taken
@@ -565,7 +575,7 @@ extern bool skb_try_coalesce(struct sk_buff *to, struct sk_buff *from,
                             bool *fragstolen, int *delta_truesize);
 
 extern struct sk_buff *__alloc_skb(unsigned int size,
-                                  gfp_t priority, int fclone, int node);
+                                  gfp_t priority, int flags, int node);
 extern struct sk_buff *build_skb(void *data, unsigned int frag_size);
 static inline struct sk_buff *alloc_skb(unsigned int size,
                                        gfp_t priority)
@@ -576,7 +586,7 @@ static inline struct sk_buff *alloc_skb(unsigned int size,
 static inline struct sk_buff *alloc_skb_fclone(unsigned int size,
                                               gfp_t priority)
 {
-       return __alloc_skb(size, priority, 1, NUMA_NO_NODE);
+       return __alloc_skb(size, priority, SKB_ALLOC_FCLONE, NUMA_NO_NODE);
 }
 
 extern void skb_recycle(struct sk_buff *skb);
@@ -1237,6 +1247,17 @@ static inline void __skb_fill_page_desc(struct sk_buff *skb, int i,
 {
        skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
 
+       /*
+        * Propagate page->pfmemalloc to the skb if we can. The problem is
+        * that not all callers have unique ownership of the page. If
+        * pfmemalloc is set, we check the mapping as a mapping implies
+        * page->index is set (index and pfmemalloc share space).
+        * If it's a valid mapping, we cannot use page->pfmemalloc but we
+        * do not lose pfmemalloc information as the pages would not be
+        * allocated using __GFP_MEMALLOC.
+        */
+       if (page->pfmemalloc && !page->mapping)
+               skb->pfmemalloc = true;
        frag->page.p              = page;
        frag->page_offset         = off;
        skb_frag_size_set(frag, size);