--- /dev/null
+From d6f1c17e162b2a11e708f28fa93f2f79c164b442 Mon Sep 17 00:00:00 2001
+From: Mike Marciniszyn <mike.marciniszyn@intel.com>
+Date: Tue, 21 Jul 2015 08:36:07 -0400
+Subject: IB/qib: Change lkey table allocation to support more MRs
+
+From: Mike Marciniszyn <mike.marciniszyn@intel.com>
+
+commit d6f1c17e162b2a11e708f28fa93f2f79c164b442 upstream.
+
+The lkey table is allocated with with a get_user_pages() with an
+order based on a number of index bits from a module parameter.
+
+The underlying kernel code cannot allocate that many contiguous pages.
+
+There is no reason the underlying memory needs to be physically
+contiguous.
+
+This patch:
+- switches the allocation/deallocation to vmalloc/vfree
+- caps the number of bits to 23 to insure at least 1 generation bit
+ o this matches the module parameter description
+
+Reviewed-by: Vinit Agnihotri <vinit.abhay.agnihotri@intel.com>
+Signed-off-by: Mike Marciniszyn <mike.marciniszyn@intel.com>
+Signed-off-by: Doug Ledford <dledford@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/infiniband/hw/qib/qib.h | 27 +++++++++++----------------
+ drivers/infiniband/hw/qib/qib_keys.c | 4 ++++
+ drivers/infiniband/hw/qib/qib_verbs.c | 14 ++++++++++----
+ drivers/infiniband/hw/qib/qib_verbs.h | 2 ++
+ 4 files changed, 27 insertions(+), 20 deletions(-)
+
+--- a/drivers/infiniband/hw/qib/qib.h
++++ b/drivers/infiniband/hw/qib/qib.h
+@@ -1467,27 +1467,22 @@ extern struct mutex qib_mutex;
+ * first to avoid possible serial port delays from printk.
+ */
+ #define qib_early_err(dev, fmt, ...) \
+- do { \
+- dev_err(dev, fmt, ##__VA_ARGS__); \
+- } while (0)
++ dev_err(dev, fmt, ##__VA_ARGS__)
+
+ #define qib_dev_err(dd, fmt, ...) \
+- do { \
+- dev_err(&(dd)->pcidev->dev, "%s: " fmt, \
+- qib_get_unit_name((dd)->unit), ##__VA_ARGS__); \
+- } while (0)
++ dev_err(&(dd)->pcidev->dev, "%s: " fmt, \
++ qib_get_unit_name((dd)->unit), ##__VA_ARGS__)
+
+-#define qib_dev_porterr(dd, port, fmt, ...) \
+- do { \
+- dev_err(&(dd)->pcidev->dev, "%s: IB%u:%u " fmt, \
+- qib_get_unit_name((dd)->unit), (dd)->unit, (port), \
+- ##__VA_ARGS__); \
+- } while (0)
++#define qib_dev_warn(dd, fmt, ...) \
++ dev_warn(&(dd)->pcidev->dev, "%s: " fmt, \
++ qib_get_unit_name((dd)->unit), ##__VA_ARGS__)
+
++#define qib_dev_porterr(dd, port, fmt, ...) \
++ dev_err(&(dd)->pcidev->dev, "%s: IB%u:%u " fmt, \
++ qib_get_unit_name((dd)->unit), (dd)->unit, (port), \
++ ##__VA_ARGS__)
+ #define qib_devinfo(pcidev, fmt, ...) \
+- do { \
+- dev_info(&(pcidev)->dev, fmt, ##__VA_ARGS__); \
+- } while (0)
++ dev_info(&(pcidev)->dev, fmt, ##__VA_ARGS__)
+
+ /*
+ * this is used for formatting hw error messages...
+--- a/drivers/infiniband/hw/qib/qib_keys.c
++++ b/drivers/infiniband/hw/qib/qib_keys.c
+@@ -86,6 +86,10 @@ int qib_alloc_lkey(struct qib_mregion *m
+ * unrestricted LKEY.
+ */
+ rkt->gen++;
++ /*
++ * bits are capped in qib_verbs.c to insure enough bits
++ * for generation number
++ */
+ mr->lkey = (r << (32 - ib_qib_lkey_table_size)) |
+ ((((1 << (24 - ib_qib_lkey_table_size)) - 1) & rkt->gen)
+ << 8);
+--- a/drivers/infiniband/hw/qib/qib_verbs.c
++++ b/drivers/infiniband/hw/qib/qib_verbs.c
+@@ -40,6 +40,7 @@
+ #include <linux/rculist.h>
+ #include <linux/mm.h>
+ #include <linux/random.h>
++#include <linux/vmalloc.h>
+
+ #include "qib.h"
+ #include "qib_common.h"
+@@ -2084,10 +2085,16 @@ int qib_register_ib_device(struct qib_de
+ * the LKEY). The remaining bits act as a generation number or tag.
+ */
+ spin_lock_init(&dev->lk_table.lock);
++ /* insure generation is at least 4 bits see keys.c */
++ if (ib_qib_lkey_table_size > MAX_LKEY_TABLE_BITS) {
++ qib_dev_warn(dd, "lkey bits %u too large, reduced to %u\n",
++ ib_qib_lkey_table_size, MAX_LKEY_TABLE_BITS);
++ ib_qib_lkey_table_size = MAX_LKEY_TABLE_BITS;
++ }
+ dev->lk_table.max = 1 << ib_qib_lkey_table_size;
+ lk_tab_size = dev->lk_table.max * sizeof(*dev->lk_table.table);
+ dev->lk_table.table = (struct qib_mregion __rcu **)
+- __get_free_pages(GFP_KERNEL, get_order(lk_tab_size));
++ vmalloc(lk_tab_size);
+ if (dev->lk_table.table == NULL) {
+ ret = -ENOMEM;
+ goto err_lk;
+@@ -2260,7 +2267,7 @@ err_tx:
+ sizeof(struct qib_pio_header),
+ dev->pio_hdrs, dev->pio_hdrs_phys);
+ err_hdrs:
+- free_pages((unsigned long) dev->lk_table.table, get_order(lk_tab_size));
++ vfree(dev->lk_table.table);
+ err_lk:
+ kfree(dev->qp_table);
+ err_qpt:
+@@ -2314,8 +2321,7 @@ void qib_unregister_ib_device(struct qib
+ sizeof(struct qib_pio_header),
+ dev->pio_hdrs, dev->pio_hdrs_phys);
+ lk_tab_size = dev->lk_table.max * sizeof(*dev->lk_table.table);
+- free_pages((unsigned long) dev->lk_table.table,
+- get_order(lk_tab_size));
++ vfree(dev->lk_table.table);
+ kfree(dev->qp_table);
+ }
+
+--- a/drivers/infiniband/hw/qib/qib_verbs.h
++++ b/drivers/infiniband/hw/qib/qib_verbs.h
+@@ -645,6 +645,8 @@ struct qib_qpn_table {
+ struct qpn_map map[QPNMAP_ENTRIES];
+ };
+
++#define MAX_LKEY_TABLE_BITS 23
++
+ struct qib_lkey_table {
+ spinlock_t lock; /* protect changes in this struct */
+ u32 next; /* next unused index (speeds search) */
--- /dev/null
+From 7c7feb2ebfc9c0552c51f0c050db1d1a004faac5 Mon Sep 17 00:00:00 2001
+From: shengyong <shengyong1@huawei.com>
+Date: Mon, 28 Sep 2015 17:57:19 +0000
+Subject: UBI: return ENOSPC if no enough space available
+
+From: shengyong <shengyong1@huawei.com>
+
+commit 7c7feb2ebfc9c0552c51f0c050db1d1a004faac5 upstream.
+
+UBI: attaching mtd1 to ubi0
+UBI: scanning is finished
+UBI error: init_volumes: not enough PEBs, required 706, available 686
+UBI error: ubi_wl_init: no enough physical eraseblocks (-20, need 1)
+UBI error: ubi_attach_mtd_dev: failed to attach mtd1, error -12 <= NOT ENOMEM
+UBI error: ubi_init: cannot attach mtd1
+
+If available PEBs are not enough when initializing volumes, return -ENOSPC
+directly. If available PEBs are not enough when initializing WL, return
+-ENOSPC instead of -ENOMEM.
+
+Signed-off-by: Sheng Yong <shengyong1@huawei.com>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Reviewed-by: David Gstir <david@sigma-star.at>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/mtd/ubi/vtbl.c | 1 +
+ drivers/mtd/ubi/wl.c | 1 +
+ 2 files changed, 2 insertions(+)
+
+--- a/drivers/mtd/ubi/vtbl.c
++++ b/drivers/mtd/ubi/vtbl.c
+@@ -651,6 +651,7 @@ static int init_volumes(struct ubi_devic
+ if (ubi->corr_peb_count)
+ ubi_err("%d PEBs are corrupted and not used",
+ ubi->corr_peb_count);
++ return -ENOSPC;
+ }
+ ubi->rsvd_pebs += reserved_pebs;
+ ubi->avail_pebs -= reserved_pebs;
+--- a/drivers/mtd/ubi/wl.c
++++ b/drivers/mtd/ubi/wl.c
+@@ -1978,6 +1978,7 @@ int ubi_wl_init(struct ubi_device *ubi,
+ if (ubi->corr_peb_count)
+ ubi_err("%d PEBs are corrupted and not used",
+ ubi->corr_peb_count);
++ err = -ENOSPC;
+ goto out_free;
+ }
+ ubi->avail_pebs -= reserved_pebs;