On 3/7/19 8:50 AM, Luca Coelho wrote: > From: Luca Coelho <luciano.coelho@xxxxxxxxx> > > RHEL 7.6 uses kernel v3.10 with a lot of backports from newer > kernels. This causes compilation to break in many places when the > backports project is used. To solve the issue, check for RHEL release > code 7.6 where appropriate. This doesn't take into consideration > lower versions of the kernel (i.e. < 7.6), because it's very difficult > to find the information about when each feature was backported. > > Signed-off-by: Luca Coelho <luciano.coelho@xxxxxxxxx> > --- > > In v2: > > * Fix some linking issues; > * Fix some duplicate symbols due to backporting stuff that was > already in RHEL's kernel; > > In v3: > > * Remove gerrit tag. > > > .../backport-include/linux/bp-devcoredump.h | 3 +- > backport/backport-include/linux/etherdevice.h | 6 +- > backport/backport-include/linux/firmware.h | 6 +- > .../backport-include/linux/ftrace_event.h | 3 +- > backport/backport-include/linux/jiffies.h | 5 + > backport/backport-include/linux/kernel.h | 3 +- > backport/backport-include/linux/ktime.h | 3 +- > backport/backport-include/linux/mm.h | 55 ++++++ > backport/backport-include/linux/moduleparam.h | 3 +- > backport/backport-include/linux/netdevice.h | 12 +- > backport/backport-include/linux/netlink.h | 3 +- > backport/backport-include/linux/page_ref.h | 3 +- > backport/backport-include/linux/pci.h | 3 +- > backport/backport-include/linux/percpu.h | 3 +- > backport/backport-include/linux/pm_runtime.h | 3 +- > backport/backport-include/linux/property.h | 3 +- > backport/backport-include/linux/rtnetlink.h | 3 +- > backport/backport-include/linux/skbuff.h | 6 +- > backport/backport-include/linux/string.h | 3 +- > backport/backport-include/linux/time.h | 6 + > backport/backport-include/linux/time64.h | 3 +- > backport/backport-include/linux/timekeeping.h | 15 +- > .../backport-include/linux/u64_stats_sync.h | 3 +- > backport/backport-include/linux/uuid.h | 3 +- > backport/backport-include/linux/wait.h | 6 +- > backport/backport-include/net/genetlink.h | 6 +- > backport/backport-include/net/inet_frag.h | 6 +- > backport/backport-include/net/iw_handler.h | 3 +- > backport/backport-include/net/net_namespace.h | 3 +- > backport/backport-include/net/netlink.h | 6 +- > backport/compat/backport-3.11.c | 2 + > backport/compat/backport-3.13.c | 3 +- > backport/compat/backport-3.17.c | 7 +- > backport/compat/backport-3.19.c | 5 +- > backport/compat/backport-4.0.c | 184 +++++++++++++++++- > backport/compat/backport-4.1.c | 2 + > backport/compat/backport-4.2.c | 4 +- > backport/compat/backport-4.4.c | 3 +- > backport/compat/backport-4.6.c | 4 +- > backport/compat/backport-4.7.c | 3 +- > backport/compat/backport-genetlink.c | 6 +- > patches/0028-select_queue/mac80211.patch | 10 +- > patches/0073-netdevice-mtu-range.cocci | 4 +- > patches/0075-ndo-stats-64.cocci | 4 +- > 44 files changed, 371 insertions(+), 59 deletions(-) > ....... > diff --git a/backport/backport-include/linux/jiffies.h b/backport/backport-include/linux/jiffies.h > index bbadcc8cd27e..caef7db30004 100644 > --- a/backport/backport-include/linux/jiffies.h > +++ b/backport/backport-include/linux/jiffies.h > @@ -1,5 +1,10 @@ > #ifndef __BACKPORT_LNIUX_JIFFIES_H > #define __BACKPORT_LNIUX_JIFFIES_H > + > +#ifndef NSEC_PER_SEC > +#define NSEC_PER_SEC 1000000000L > +#endif This is strange, why is this only needed on RHEL? ..... > diff --git a/backport/backport-include/linux/mm.h b/backport/backport-include/linux/mm.h > index b28156d33625..0806f4df8f5d 100644 > --- a/backport/backport-include/linux/mm.h > +++ b/backport/backport-include/linux/mm.h > @@ -12,6 +12,61 @@ > void kvfree(const void *addr); > #endif /* < 3.15 */ > > +#if LINUX_VERSION_IS_LESS(3,20,0) && \ > + RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,6) > +#define get_user_pages_locked LINUX_BACKPORT(get_user_pages_locked) > +long get_user_pages_locked(unsigned long start, unsigned long nr_pages, > + int write, int force, struct page **pages, int *locked); > +#define get_user_pages_unlocked LINUX_BACKPORT(get_user_pages_unlocked) > +long get_user_pages_unlocked(unsigned long start, unsigned long nr_pages, > + int write, int force, struct page **pages); > +#elif LINUX_VERSION_IS_LESS(4,6,0) && \ > + RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,6) > +static inline > +long backport_get_user_pages_locked(unsigned long start, unsigned long nr_pages, > + int write, int force, struct page **pages, int *locked) > +{ > + return get_user_pages_locked(current, current->mm, start, nr_pages, > + write, force, pages, locked); > +} > +#define get_user_pages_locked LINUX_BACKPORT(get_user_pages_locked) > + > +static inline > +long backport_get_user_pages_unlocked(unsigned long start, unsigned long nr_pages, > + int write, int force, struct page **pages) > +{ > + return get_user_pages_unlocked(current, current->mm, start, nr_pages, > + write, force, pages); > +} > +#define get_user_pages_unlocked LINUX_BACKPORT(get_user_pages_unlocked) > +#endif > + > +#if LINUX_VERSION_IS_LESS(4,6,0) > +static inline > +long backport_get_user_pages(unsigned long start, unsigned long nr_pages, > + int write, int force, struct page **pages, > + struct vm_area_struct **vmas) > +{ > + return get_user_pages(current, current->mm, start, nr_pages, > + write, force, pages, vmas); > +} > +#define get_user_pages LINUX_BACKPORT(get_user_pages) > +#endif > + > +#ifndef FOLL_TRIED > +#define FOLL_TRIED 0x800 /* a retry, previous pass started an IO */ > +#endif > + > +#if LINUX_VERSION_IS_LESS(4,1,9) && \ > + LINUX_VERSION_IS_GEQ(3,6,0) && \ > + RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,6) > +#define page_is_pfmemalloc LINUX_BACKPORT(page_is_pfmemalloc) > +static inline bool page_is_pfmemalloc(struct page *page) > +{ > + return page->pfmemalloc; > +} > +#endif /* < 4.2 */ > + I think these functions are not used anywhere, they wrere added for the media backports. I had some compile problems here and just removed them. > diff --git a/backport/compat/backport-4.0.c b/backport/compat/backport-4.0.c > index 84a4c6bf27b7..0439bfa32abd 100644 > --- a/backport/compat/backport-4.0.c > +++ b/backport/compat/backport-4.0.c > @@ -17,6 +17,185 @@ > #include <linux/trace_seq.h> > #include <asm/unaligned.h> > > +#if RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,6) > + static __always_inline long __get_user_pages_locked(struct task_struct *tsk, > + struct mm_struct *mm, > + unsigned long start, > + unsigned long nr_pages, > + int write, int force, > + struct page **pages, > + struct vm_area_struct **vmas, > + int *locked, bool notify_drop, > + unsigned int flags) > +{ > + long ret, pages_done; > + bool lock_dropped; > + > + if (locked) { > + /* if VM_FAULT_RETRY can be returned, vmas become invalid */ > + BUG_ON(vmas); > + /* check caller initialized locked */ > + BUG_ON(*locked != 1); > + } > + > + if (pages) > + flags |= FOLL_GET; > + if (write) > + flags |= FOLL_WRITE; > + if (force) > + flags |= FOLL_FORCE; > + > + pages_done = 0; > + lock_dropped = false; > + for (;;) { > + ret = __get_user_pages(tsk, mm, start, nr_pages, flags, pages, > + vmas, locked); > + if (!locked) > + /* VM_FAULT_RETRY couldn't trigger, bypass */ > + return ret; > + > + /* VM_FAULT_RETRY cannot return errors */ > + if (!*locked) { > + BUG_ON(ret < 0); > + BUG_ON(ret >= nr_pages); > + } > + > + if (!pages) > + /* If it's a prefault don't insist harder */ > + return ret; > + > + if (ret > 0) { > + nr_pages -= ret; > + pages_done += ret; > + if (!nr_pages) > + break; > + } > + if (*locked) { > + /* VM_FAULT_RETRY didn't trigger */ > + if (!pages_done) > + pages_done = ret; > + break; > + } > + /* VM_FAULT_RETRY triggered, so seek to the faulting offset */ > + pages += ret; > + start += ret << PAGE_SHIFT; > + > + /* > + * Repeat on the address that fired VM_FAULT_RETRY > + * without FAULT_FLAG_ALLOW_RETRY but with > + * FAULT_FLAG_TRIED. > + */ > + *locked = 1; > + lock_dropped = true; > + down_read(&mm->mmap_sem); > + ret = __get_user_pages(tsk, mm, start, 1, flags | FOLL_TRIED, > + pages, NULL, NULL); > + if (ret != 1) { > + BUG_ON(ret > 1); > + if (!pages_done) > + pages_done = ret; > + break; > + } > + nr_pages--; > + pages_done++; > + if (!nr_pages) > + break; > + pages++; > + start += PAGE_SIZE; > + } > + if (notify_drop && lock_dropped && *locked) { > + /* > + * We must let the caller know we temporarily dropped the lock > + * and so the critical section protected by it was lost. > + */ > + up_read(&mm->mmap_sem); > + *locked = 0; > + } > + return pages_done; > +} > + > +/* > + * We can leverage the VM_FAULT_RETRY functionality in the page fault > + * paths better by using either get_user_pages_locked() or > + * get_user_pages_unlocked(). > + * > + * get_user_pages_locked() is suitable to replace the form: > + * > + * down_read(&mm->mmap_sem); > + * do_something() > + * get_user_pages(tsk, mm, ..., pages, NULL); > + * up_read(&mm->mmap_sem); > + * > + * to: > + * > + * int locked = 1; > + * down_read(&mm->mmap_sem); > + * do_something() > + * get_user_pages_locked(tsk, mm, ..., pages, &locked); > + * if (locked) > + * up_read(&mm->mmap_sem); > + */ > +long get_user_pages_locked(unsigned long start, unsigned long nr_pages, > + int write, int force, struct page **pages, > + int *locked) > +{ > + return __get_user_pages_locked(current, current->mm, start, nr_pages, > + write, force, pages, NULL, locked, true, > + FOLL_TOUCH); > +} > +EXPORT_SYMBOL_GPL(get_user_pages_locked); > + > +/* > + * Same as get_user_pages_unlocked(...., FOLL_TOUCH) but it allows to > + * pass additional gup_flags as last parameter (like FOLL_HWPOISON). > + * > + * NOTE: here FOLL_TOUCH is not set implicitly and must be set by the > + * caller if required (just like with __get_user_pages). "FOLL_GET", > + * "FOLL_WRITE" and "FOLL_FORCE" are set implicitly as needed > + * according to the parameters "pages", "write", "force" > + * respectively. > + */ > +static __always_inline long __get_user_pages_unlocked(struct task_struct *tsk, struct mm_struct *mm, > + unsigned long start, unsigned long nr_pages, > + int write, int force, struct page **pages, > + unsigned int gup_flags) > +{ > + long ret; > + int locked = 1; > + down_read(&mm->mmap_sem); > + ret = __get_user_pages_locked(tsk, mm, start, nr_pages, write, force, > + pages, NULL, &locked, false, gup_flags); > + if (locked) > + up_read(&mm->mmap_sem); > + return ret; > +} > + > +/* > + * get_user_pages_unlocked() is suitable to replace the form: > + * > + * down_read(&mm->mmap_sem); > + * get_user_pages(tsk, mm, ..., pages, NULL); > + * up_read(&mm->mmap_sem); > + * > + * with: > + * > + * get_user_pages_unlocked(tsk, mm, ..., pages); > + * > + * It is functionally equivalent to get_user_pages_fast so > + * get_user_pages_fast should be used instead, if the two parameters > + * "tsk" and "mm" are respectively equal to current and current->mm, > + * or if "force" shall be set to 1 (get_user_pages_fast misses the > + * "force" parameter). > + */ > +long get_user_pages_unlocked(unsigned long start, unsigned long nr_pages, > + int write, int force, struct page **pages) > +{ > + return __get_user_pages_unlocked(current, current->mm, start, nr_pages, > + write, force, pages, FOLL_TOUCH); > +} > +EXPORT_SYMBOL_GPL(get_user_pages_unlocked); > +#endif > + > /** > * hex_dump_to_buffer - convert a blob of data to "hex ASCII" in memory > * @buf: data blob to dump I think this also not needed. Hauke -- To unsubscribe from this list: send the line "unsubscribe backports" in