Re: [PATCH v3] backports: handle RHEL 7.6 kernel

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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



[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux