]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
Merge tag 'for-f2fs-v4.13-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/jaege...
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 20 Jul 2017 17:30:16 +0000 (10:30 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 20 Jul 2017 17:30:16 +0000 (10:30 -0700)
Pull f2fs fixes from Jaegeuk Kim:
 "We've filed some bug fixes:

   - missing f2fs case in terms of stale SGID bit, introduced by Jan

   - build error for seq_file.h

   - avoid cpu lockup

   - wrong inode_unlock in error case"

* tag 'for-f2fs-v4.13-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs:
  f2fs: avoid cpu lockup
  f2fs: include seq_file.h for sysfs.c
  f2fs: Don't clear SGID when inheriting ACLs
  f2fs: remove extra inode_unlock() in error path

129 files changed:
MAINTAINERS
arch/arm/include/asm/cacheflush.h
arch/blackfin/include/asm/flat.h
arch/blackfin/kernel/flat.c
arch/h8300/include/asm/flat.h
arch/m68k/include/asm/flat.h
arch/sparc/include/asm/trap_block.h
arch/sparc/kernel/pci_sun4v.c
arch/sparc/kernel/smp_64.c
arch/sparc/kernel/sun4v_ivec.S
arch/sparc/kernel/traps_64.c
arch/x86/include/asm/paravirt_types.h
arch/x86/include/asm/processor.h
drivers/acpi/nfit/core.c
drivers/base/regmap/regmap-w1.c
drivers/dax/device-dax.h
drivers/dax/device.c
drivers/dax/pmem.c
drivers/hid/hid-logitech-hidpp.c
drivers/hid/hid-multitouch.c
drivers/infiniband/core/addr.c
drivers/infiniband/core/cma.c
drivers/infiniband/core/roce_gid_mgmt.c
drivers/infiniband/core/uverbs_cmd.c
drivers/infiniband/core/verbs.c
drivers/infiniband/hw/hfi1/chip.c
drivers/infiniband/hw/hfi1/qp.c
drivers/infiniband/hw/hfi1/qp.h
drivers/infiniband/hw/hns/hns_roce_hw_v1.c
drivers/infiniband/hw/hns/hns_roce_main.c
drivers/infiniband/hw/mlx4/cq.c
drivers/infiniband/hw/mlx4/main.c
drivers/infiniband/hw/mlx4/mcg.c
drivers/infiniband/hw/mlx4/mlx4_ib.h
drivers/infiniband/hw/mlx4/qp.c
drivers/infiniband/hw/mlx4/srq.c
drivers/infiniband/hw/mlx5/mr.c
drivers/infiniband/hw/nes/nes_hw.c
drivers/infiniband/hw/qib/qib_qp.c
drivers/infiniband/hw/qib/qib_verbs.h
drivers/infiniband/sw/rdmavt/qp.c
drivers/infiniband/sw/rxe/rxe_net.c
drivers/infiniband/sw/rxe/rxe_verbs.c
drivers/infiniband/ulp/ipoib/ipoib_cm.c
drivers/infiniband/ulp/ipoib/ipoib_ib.c
drivers/infiniband/ulp/ipoib/ipoib_main.c
drivers/infiniband/ulp/iser/iscsi_iser.c
drivers/infiniband/ulp/iser/iser_verbs.c
drivers/md/bitmap.c
drivers/md/md.h
drivers/md/raid5-ppl.c
drivers/md/raid5.c
drivers/net/ethernet/mellanox/mlx4/alloc.c
drivers/net/ethernet/mellanox/mlx4/cq.c
drivers/net/ethernet/mellanox/mlx4/en_rx.c
drivers/net/ethernet/mellanox/mlx4/en_tx.c
drivers/net/ethernet/mellanox/mlx4/icm.c
drivers/net/ethernet/mellanox/mlx4/icm.h
drivers/net/ethernet/mellanox/mlx4/mlx4.h
drivers/net/ethernet/mellanox/mlx4/mr.c
drivers/net/ethernet/mellanox/mlx4/qp.c
drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
drivers/net/ethernet/mellanox/mlx4/srq.c
drivers/nvdimm/core.c
drivers/scsi/cxlflash/main.c
drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
drivers/scsi/isci/request.c
drivers/scsi/libfc/fc_disc.c
drivers/scsi/qedf/qedf_main.c
drivers/scsi/qedi/qedi.h
drivers/scsi/qedi/qedi_fw.c
drivers/scsi/qedi/qedi_main.c
drivers/scsi/qedi/qedi_nvm_iscsi_cfg.h [new file with mode: 0644]
drivers/scsi/qla2xxx/qla_target.c
drivers/scsi/sg.c
drivers/scsi/virtio_scsi.c
fs/binfmt_flat.c
fs/ceph/dir.c
fs/mount.h
fs/namei.c
fs/nfsd/nfs4callback.c
fs/proc/internal.h
include/linux/binfmts.h
include/linux/cdev.h
include/linux/ceph/ceph_features.h
include/linux/compiler-gcc.h
include/linux/compiler.h
include/linux/cred.h
include/linux/dcache.h
include/linux/fs.h
include/linux/fs_struct.h
include/linux/ipc.h
include/linux/ipc_namespace.h
include/linux/key-type.h
include/linux/kmod.h
include/linux/kobject.h
include/linux/llist.h
include/linux/lsm_hooks.h
include/linux/mlx4/device.h
include/linux/mm_types.h
include/linux/module.h
include/linux/mount.h
include/linux/msg.h
include/linux/path.h
include/linux/pid_namespace.h
include/linux/proc_ns.h
include/linux/sched.h
include/linux/sched/signal.h
include/linux/sem.h
include/linux/shm.h
include/linux/sysctl.h
include/linux/tty.h
include/linux/tty_driver.h
include/linux/user_namespace.h
include/linux/utsname.h
include/net/af_unix.h
include/net/neighbour.h
include/net/net_namespace.h
include/net/sock.h
include/rdma/ib_verbs.h
include/rdma/rdma_vt.h
kernel/audit.c
kernel/cpu.c
kernel/futex.c
kernel/irq/manage.c
net/ceph/messenger.c
net/ceph/osd_client.c
net/ceph/osdmap.c
security/keys/internal.h

index 205d3977ac46e1a3bf58d95b46df5db29eabc70f..297e610c9163a3186c1f960a6898e1fec902cafa 100644 (file)
@@ -7730,6 +7730,7 @@ Q:        https://patchwork.kernel.org/project/linux-nvdimm/list/
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm.git
 S:     Supported
 F:     drivers/nvdimm/*
+F:     drivers/acpi/nfit/*
 F:     include/linux/nd.h
 F:     include/linux/libnvdimm.h
 F:     include/uapi/linux/ndctl.h
@@ -7741,7 +7742,6 @@ Q:        https://patchwork.kernel.org/project/linux-nvdimm/list/
 S:     Supported
 F:     drivers/nvdimm/blk.c
 F:     drivers/nvdimm/region_devs.c
-F:     drivers/acpi/nfit*
 
 LIBNVDIMM BTT: BLOCK TRANSLATION TABLE
 M:     Vishal Verma <vishal.l.verma@intel.com>
@@ -10868,6 +10868,14 @@ L:     linux-scsi@vger.kernel.org
 S:     Supported
 F:     drivers/scsi/qedf/
 
+QLOGIC QL4xxx RDMA DRIVER
+M:     Ram Amrani <Ram.Amrani@cavium.com>
+M:     Ariel Elior <Ariel.Elior@cavium.com>
+L:     linux-rdma@vger.kernel.org
+S:     Supported
+F:     drivers/infiniband/hw/qedr/
+F:     include/uapi/rdma/qedr-abi.h
+
 QNX4 FILESYSTEM
 M:     Anders Larsen <al@alarsen.net>
 W:     http://www.alarsen.net/linux/qnx4fs/
index d69bebf697e76d2003bb671645290c938a156abd..74504b154256e36ff4897ed1c7df43eb4d91bdef 100644 (file)
@@ -116,7 +116,7 @@ struct cpu_cache_fns {
        void (*dma_unmap_area)(const void *, size_t, int);
 
        void (*dma_flush_range)(const void *, const void *);
-};
+} __no_randomize_layout;
 
 /*
  * Select the calling method
index 296d7f56fbfd005bb77b264474a179bcfb81bc61..f1d6ba7afbf245a0e593bf9aba7aad6229902ca8 100644 (file)
@@ -44,8 +44,7 @@ flat_get_relocate_addr (unsigned long relval)
        return relval & 0x03ffffff; /* Mask out top 6 bits */
 }
 
-static inline int flat_set_persistent(unsigned long relval,
-                                     unsigned long *persistent)
+static inline int flat_set_persistent(u32 relval, u32 *persistent)
 {
        int type = (relval >> 26) & 7;
        if (type == 3) {
index d29ab6a2e909f301154a65409847f2b0a5256871..8ebc54daaa8e9d7c141ae1fd21d072812b0746ae 100644 (file)
@@ -32,7 +32,7 @@ unsigned long bfin_get_addr_from_rp(u32 *ptr,
                break;
 
        case FLAT_BFIN_RELOC_TYPE_32_BIT:
-               pr_debug("*ptr = %lx", get_unaligned(ptr));
+               pr_debug("*ptr = %x", get_unaligned(ptr));
                val = get_unaligned(ptr);
                break;
 
@@ -77,7 +77,7 @@ void bfin_put_addr_at_rp(u32 *ptr, u32 addr, u32 relval)
 
        case FLAT_BFIN_RELOC_TYPE_32_BIT:
                put_unaligned(addr, ptr);
-               pr_debug("new ptr =%lx", get_unaligned(ptr));
+               pr_debug("new ptr =%x", get_unaligned(ptr));
                break;
        }
 }
index 18d024251738dd4e8499f0687842ce776c59816f..7e0bd6fa15324495ea5875fd3180c7f8081c54e3 100644 (file)
@@ -24,7 +24,7 @@ static inline int flat_get_addr_from_rp(u32 __user *rp, u32 relval, u32 flags,
                                        u32 *addr, u32 *persistent)
 {
        u32 val = get_unaligned((__force u32 *)rp);
-       if (!(flags & FLAT_FLAG_GOTPIC)
+       if (!(flags & FLAT_FLAG_GOTPIC))
                val &= 0x00ffffff;
        *addr = val;
        return 0;
index 48b62790fe70f1a620b0f5e47d0546e07ed77664..b2a41f5b3890a524d0335b89aaa3111194cd189d 100644 (file)
@@ -30,8 +30,7 @@ static inline int flat_put_addr_at_rp(u32 __user *rp, u32 addr, u32 rel)
 }
 #define        flat_get_relocate_addr(rel)             (rel)
 
-static inline int flat_set_persistent(unsigned long relval,
-                                     unsigned long *persistent)
+static inline int flat_set_persistent(u32 relval, u32 *persistent)
 {
        return 0;
 }
index ec9c04de3664910d81b7a55bbb09084d5e235d39..ff05992dae7a352597bf99fcd2d83500ad0c2995 100644 (file)
@@ -54,6 +54,7 @@ extern struct trap_per_cpu trap_block[NR_CPUS];
 void init_cur_cpu_trap(struct thread_info *);
 void setup_tba(void);
 extern int ncpus_probed;
+extern u64 cpu_mondo_counter[NR_CPUS];
 
 unsigned long real_hard_smp_processor_id(void);
 
index 24f21c726dfad7474da03d6a4a80f329843ff8e4..f10e2f7123949dedc8904ea37895d402ed097d2b 100644 (file)
@@ -673,12 +673,14 @@ static void dma_4v_unmap_sg(struct device *dev, struct scatterlist *sglist,
 static int dma_4v_supported(struct device *dev, u64 device_mask)
 {
        struct iommu *iommu = dev->archdata.iommu;
-       u64 dma_addr_mask;
+       u64 dma_addr_mask = iommu->dma_addr_mask;
 
-       if (device_mask > DMA_BIT_MASK(32) && iommu->atu)
-               dma_addr_mask = iommu->atu->dma_addr_mask;
-       else
-               dma_addr_mask = iommu->dma_addr_mask;
+       if (device_mask > DMA_BIT_MASK(32)) {
+               if (iommu->atu)
+                       dma_addr_mask = iommu->atu->dma_addr_mask;
+               else
+                       return 0;
+       }
 
        if ((device_mask & dma_addr_mask) == dma_addr_mask)
                return 1;
index fdf31040a7dc5cc460de6d60c9724a60933b38dc..3218bc43302e1cbbfc48420d868f5148a8d61085 100644 (file)
@@ -622,22 +622,48 @@ retry:
        }
 }
 
-/* Multi-cpu list version.  */
+#define        CPU_MONDO_COUNTER(cpuid)        (cpu_mondo_counter[cpuid])
+#define        MONDO_USEC_WAIT_MIN             2
+#define        MONDO_USEC_WAIT_MAX             100
+#define        MONDO_RETRY_LIMIT               500000
+
+/* Multi-cpu list version.
+ *
+ * Deliver xcalls to 'cnt' number of cpus in 'cpu_list'.
+ * Sometimes not all cpus receive the mondo, requiring us to re-send
+ * the mondo until all cpus have received, or cpus are truly stuck
+ * unable to receive mondo, and we timeout.
+ * Occasionally a target cpu strand is borrowed briefly by hypervisor to
+ * perform guest service, such as PCIe error handling. Consider the
+ * service time, 1 second overall wait is reasonable for 1 cpu.
+ * Here two in-between mondo check wait time are defined: 2 usec for
+ * single cpu quick turn around and up to 100usec for large cpu count.
+ * Deliver mondo to large number of cpus could take longer, we adjusts
+ * the retry count as long as target cpus are making forward progress.
+ */
 static void hypervisor_xcall_deliver(struct trap_per_cpu *tb, int cnt)
 {
-       int retries, this_cpu, prev_sent, i, saw_cpu_error;
+       int this_cpu, tot_cpus, prev_sent, i, rem;
+       int usec_wait, retries, tot_retries;
+       u16 first_cpu = 0xffff;
+       unsigned long xc_rcvd = 0;
        unsigned long status;
+       int ecpuerror_id = 0;
+       int enocpu_id = 0;
        u16 *cpu_list;
+       u16 cpu;
 
        this_cpu = smp_processor_id();
-
        cpu_list = __va(tb->cpu_list_pa);
-
-       saw_cpu_error = 0;
-       retries = 0;
+       usec_wait = cnt * MONDO_USEC_WAIT_MIN;
+       if (usec_wait > MONDO_USEC_WAIT_MAX)
+               usec_wait = MONDO_USEC_WAIT_MAX;
+       retries = tot_retries = 0;
+       tot_cpus = cnt;
        prev_sent = 0;
+
        do {
-               int forward_progress, n_sent;
+               int n_sent, mondo_delivered, target_cpu_busy;
 
                status = sun4v_cpu_mondo_send(cnt,
                                              tb->cpu_list_pa,
@@ -645,94 +671,113 @@ static void hypervisor_xcall_deliver(struct trap_per_cpu *tb, int cnt)
 
                /* HV_EOK means all cpus received the xcall, we're done.  */
                if (likely(status == HV_EOK))
-                       break;
+                       goto xcall_done;
+
+               /* If not these non-fatal errors, panic */
+               if (unlikely((status != HV_EWOULDBLOCK) &&
+                       (status != HV_ECPUERROR) &&
+                       (status != HV_ENOCPU)))
+                       goto fatal_errors;
 
                /* First, see if we made any forward progress.
+                *
+                * Go through the cpu_list, count the target cpus that have
+                * received our mondo (n_sent), and those that did not (rem).
+                * Re-pack cpu_list with the cpus remain to be retried in the
+                * front - this simplifies tracking the truly stalled cpus.
                 *
                 * The hypervisor indicates successful sends by setting
                 * cpu list entries to the value 0xffff.
+                *
+                * EWOULDBLOCK means some target cpus did not receive the
+                * mondo and retry usually helps.
+                *
+                * ECPUERROR means at least one target cpu is in error state,
+                * it's usually safe to skip the faulty cpu and retry.
+                *
+                * ENOCPU means one of the target cpu doesn't belong to the
+                * domain, perhaps offlined which is unexpected, but not
+                * fatal and it's okay to skip the offlined cpu.
                 */
+               rem = 0;
                n_sent = 0;
                for (i = 0; i < cnt; i++) {
-                       if (likely(cpu_list[i] == 0xffff))
+                       cpu = cpu_list[i];
+                       if (likely(cpu == 0xffff)) {
                                n_sent++;
+                       } else if ((status == HV_ECPUERROR) &&
+                               (sun4v_cpu_state(cpu) == HV_CPU_STATE_ERROR)) {
+                               ecpuerror_id = cpu + 1;
+                       } else if (status == HV_ENOCPU && !cpu_online(cpu)) {
+                               enocpu_id = cpu + 1;
+                       } else {
+                               cpu_list[rem++] = cpu;
+                       }
                }
 
-               forward_progress = 0;
-               if (n_sent > prev_sent)
-                       forward_progress = 1;
+               /* No cpu remained, we're done. */
+               if (rem == 0)
+                       break;
 
-               prev_sent = n_sent;
+               /* Otherwise, update the cpu count for retry. */
+               cnt = rem;
 
-               /* If we get a HV_ECPUERROR, then one or more of the cpus
-                * in the list are in error state.  Use the cpu_state()
-                * hypervisor call to find out which cpus are in error state.
+               /* Record the overall number of mondos received by the
+                * first of the remaining cpus.
                 */
-               if (unlikely(status == HV_ECPUERROR)) {
-                       for (i = 0; i < cnt; i++) {
-                               long err;
-                               u16 cpu;
+               if (first_cpu != cpu_list[0]) {
+                       first_cpu = cpu_list[0];
+                       xc_rcvd = CPU_MONDO_COUNTER(first_cpu);
+               }
 
-                               cpu = cpu_list[i];
-                               if (cpu == 0xffff)
-                                       continue;
+               /* Was any mondo delivered successfully? */
+               mondo_delivered = (n_sent > prev_sent);
+               prev_sent = n_sent;
 
-                               err = sun4v_cpu_state(cpu);
-                               if (err == HV_CPU_STATE_ERROR) {
-                                       saw_cpu_error = (cpu + 1);
-                                       cpu_list[i] = 0xffff;
-                               }
-                       }
-               } else if (unlikely(status != HV_EWOULDBLOCK))
-                       goto fatal_mondo_error;
+               /* or, was any target cpu busy processing other mondos? */
+               target_cpu_busy = (xc_rcvd < CPU_MONDO_COUNTER(first_cpu));
+               xc_rcvd = CPU_MONDO_COUNTER(first_cpu);
 
-               /* Don't bother rewriting the CPU list, just leave the
-                * 0xffff and non-0xffff entries in there and the
-                * hypervisor will do the right thing.
-                *
-                * Only advance timeout state if we didn't make any
-                * forward progress.
+               /* Retry count is for no progress. If we're making progress,
+                * reset the retry count.
                 */
-               if (unlikely(!forward_progress)) {
-                       if (unlikely(++retries > 10000))
-                               goto fatal_mondo_timeout;
-
-                       /* Delay a little bit to let other cpus catch up
-                        * on their cpu mondo queue work.
-                        */
-                       udelay(2 * cnt);
+               if (likely(mondo_delivered || target_cpu_busy)) {
+                       tot_retries += retries;
+                       retries = 0;
+               } else if (unlikely(retries > MONDO_RETRY_LIMIT)) {
+                       goto fatal_mondo_timeout;
                }
-       } while (1);
 
-       if (unlikely(saw_cpu_error))
-               goto fatal_mondo_cpu_error;
+               /* Delay a little bit to let other cpus catch up on
+                * their cpu mondo queue work.
+                */
+               if (!mondo_delivered)
+                       udelay(usec_wait);
 
-       return;
+               retries++;
+       } while (1);
 
-fatal_mondo_cpu_error:
-       printk(KERN_CRIT "CPU[%d]: SUN4V mondo cpu error, some target cpus "
-              "(including %d) were in error state\n",
-              this_cpu, saw_cpu_error - 1);
+xcall_done:
+       if (unlikely(ecpuerror_id > 0)) {
+               pr_crit("CPU[%d]: SUN4V mondo cpu error, target cpu(%d) was in error state\n",
+                      this_cpu, ecpuerror_id - 1);
+       } else if (unlikely(enocpu_id > 0)) {
+               pr_crit("CPU[%d]: SUN4V mondo cpu error, target cpu(%d) does not belong to the domain\n",
+                      this_cpu, enocpu_id - 1);
+       }
        return;
 
+fatal_errors:
+       /* fatal errors include bad alignment, etc */
+       pr_crit("CPU[%d]: Args were cnt(%d) cpulist_pa(%lx) mondo_block_pa(%lx)\n",
+              this_cpu, tot_cpus, tb->cpu_list_pa, tb->cpu_mondo_block_pa);
+       panic("Unexpected SUN4V mondo error %lu\n", status);
+
 fatal_mondo_timeout:
-       printk(KERN_CRIT "CPU[%d]: SUN4V mondo timeout, no forward "
-              " progress after %d retries.\n",
-              this_cpu, retries);
-       goto dump_cpu_list_and_out;
-
-fatal_mondo_error:
-       printk(KERN_CRIT "CPU[%d]: Unexpected SUN4V mondo error %lu\n",
-              this_cpu, status);
-       printk(KERN_CRIT "CPU[%d]: Args were cnt(%d) cpulist_pa(%lx) "
-              "mondo_block_pa(%lx)\n",
-              this_cpu, cnt, tb->cpu_list_pa, tb->cpu_mondo_block_pa);
-
-dump_cpu_list_and_out:
-       printk(KERN_CRIT "CPU[%d]: CPU list [ ", this_cpu);
-       for (i = 0; i < cnt; i++)
-               printk("%u ", cpu_list[i]);
-       printk("]\n");
+       /* some cpus being non-responsive to the cpu mondo */
+       pr_crit("CPU[%d]: SUN4V mondo timeout, cpu(%d) made no forward progress after %d retries. Total target cpus(%d).\n",
+              this_cpu, first_cpu, (tot_retries + retries), tot_cpus);
+       panic("SUN4V mondo timeout panic\n");
 }
 
 static void (*xcall_deliver_impl)(struct trap_per_cpu *, int);
index 559bc5e9c199232d092ec425d705a016b639db9a..34631995859afb2c273f3087796ff550371bc634 100644 (file)
@@ -26,6 +26,21 @@ sun4v_cpu_mondo:
        ldxa    [%g0] ASI_SCRATCHPAD, %g4
        sub     %g4, TRAP_PER_CPU_FAULT_INFO, %g4
 
+       /* Get smp_processor_id() into %g3 */
+       sethi   %hi(trap_block), %g5
+       or      %g5, %lo(trap_block), %g5
+       sub     %g4, %g5, %g3
+       srlx    %g3, TRAP_BLOCK_SZ_SHIFT, %g3
+
+       /* Increment cpu_mondo_counter[smp_processor_id()] */
+       sethi   %hi(cpu_mondo_counter), %g5
+       or      %g5, %lo(cpu_mondo_counter), %g5
+       sllx    %g3, 3, %g3
+       add     %g5, %g3, %g5
+       ldx     [%g5], %g3
+       add     %g3, 1, %g3
+       stx     %g3, [%g5]
+
        /* Get CPU mondo queue base phys address into %g7.  */
        ldx     [%g4 + TRAP_PER_CPU_CPU_MONDO_PA], %g7
 
index 196ee5eb4d489b156d677f079f545e6ff792289d..ad31af1dd726575986c87bba514b345f291342ec 100644 (file)
@@ -2733,6 +2733,7 @@ void do_getpsr(struct pt_regs *regs)
        }
 }
 
+u64 cpu_mondo_counter[NR_CPUS] = {0};
 struct trap_per_cpu trap_block[NR_CPUS];
 EXPORT_SYMBOL(trap_block);
 
index cb976bab62996332f8b808ebaa18315d35005679..9ffc36bfe4cddfb96a019ceea43c074a9be682de 100644 (file)
@@ -84,7 +84,7 @@ struct pv_init_ops {
         */
        unsigned (*patch)(u8 type, u16 clobber, void *insnbuf,
                          unsigned long addr, unsigned len);
-};
+} __no_randomize_layout;
 
 
 struct pv_lazy_ops {
@@ -92,12 +92,12 @@ struct pv_lazy_ops {
        void (*enter)(void);
        void (*leave)(void);
        void (*flush)(void);
-};
+} __no_randomize_layout;
 
 struct pv_time_ops {
        unsigned long long (*sched_clock)(void);
        unsigned long long (*steal_clock)(int cpu);
-};
+} __no_randomize_layout;
 
 struct pv_cpu_ops {
        /* hooks for various privileged instructions */
@@ -176,7 +176,7 @@ struct pv_cpu_ops {
 
        void (*start_context_switch)(struct task_struct *prev);
        void (*end_context_switch)(struct task_struct *next);
-};
+} __no_randomize_layout;
 
 struct pv_irq_ops {
        /*
@@ -199,7 +199,7 @@ struct pv_irq_ops {
 #ifdef CONFIG_X86_64
        void (*adjust_exception_frame)(void);
 #endif
-};
+} __no_randomize_layout;
 
 struct pv_mmu_ops {
        unsigned long (*read_cr2)(void);
@@ -305,7 +305,7 @@ struct pv_mmu_ops {
           an mfn.  We can tell which is which from the index. */
        void (*set_fixmap)(unsigned /* enum fixed_addresses */ idx,
                           phys_addr_t phys, pgprot_t flags);
-};
+} __no_randomize_layout;
 
 struct arch_spinlock;
 #ifdef CONFIG_SMP
@@ -322,7 +322,7 @@ struct pv_lock_ops {
        void (*kick)(int cpu);
 
        struct paravirt_callee_save vcpu_is_preempted;
-};
+} __no_randomize_layout;
 
 /* This contains all the paravirt structures: we get a convenient
  * number for each function using the offset which we use to indicate
@@ -334,7 +334,7 @@ struct paravirt_patch_template {
        struct pv_irq_ops pv_irq_ops;
        struct pv_mmu_ops pv_mmu_ops;
        struct pv_lock_ops pv_lock_ops;
-};
+} __no_randomize_layout;
 
 extern struct pv_info pv_info;
 extern struct pv_init_ops pv_init_ops;
index 6a79547e8ee01e06a84cc948f0d9a61002cdda82..028245e1c42b23d1498643427ebb73be25ded661 100644 (file)
@@ -129,7 +129,7 @@ struct cpuinfo_x86 {
        /* Index into per_cpu list: */
        u16                     cpu_index;
        u32                     microcode;
-};
+} __randomize_layout;
 
 struct cpuid_regs {
        u32 eax, ebx, ecx, edx;
index b75b734ee73addc621c26710d8dfed1cbbe05fba..19182d091587382e0b94e9354f9c442ea90624a3 100644 (file)
@@ -3160,6 +3160,8 @@ static struct acpi_driver acpi_nfit_driver = {
 
 static __init int nfit_init(void)
 {
+       int ret;
+
        BUILD_BUG_ON(sizeof(struct acpi_table_nfit) != 40);
        BUILD_BUG_ON(sizeof(struct acpi_nfit_system_address) != 56);
        BUILD_BUG_ON(sizeof(struct acpi_nfit_memory_map) != 48);
@@ -3187,8 +3189,14 @@ static __init int nfit_init(void)
                return -ENOMEM;
 
        nfit_mce_register();
+       ret = acpi_bus_register_driver(&acpi_nfit_driver);
+       if (ret) {
+               nfit_mce_unregister();
+               destroy_workqueue(nfit_wq);
+       }
+
+       return ret;
 
-       return acpi_bus_register_driver(&acpi_nfit_driver);
 }
 
 static __exit void nfit_exit(void)
index 5f04e7bf063e1b24413bbbf2f9dd6fe6bd53471e..e6c64b0be5b21a7414e32f62c52983a7b239990c 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Register map access API - W1 (1-Wire) support
  *
- * Copyright (C) 2017 OAO Radioavionica
+ * Copyright (c) 2017 Radioavionica Corporation
  * Author: Alex A. Mihaylov <minimumlaw@rambler.ru>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -11,7 +11,7 @@
 
 #include <linux/regmap.h>
 #include <linux/module.h>
-#include "../../w1/w1.h"
+#include <linux/w1.h>
 
 #include "internal.h"
 
index fdcd9769ffded4eb4885bf20735e4fd60ca761e8..688b051750bd7cc615849491605bc0ecf50d9101 100644 (file)
@@ -21,5 +21,5 @@ struct dax_region *alloc_dax_region(struct device *parent,
                int region_id, struct resource *res, unsigned int align,
                void *addr, unsigned long flags);
 struct dev_dax *devm_create_dev_dax(struct dax_region *dax_region,
-               struct resource *res, int count);
+               int id, struct resource *res, int count);
 #endif /* __DEVICE_DAX_H__ */
index 12943d19bfc43ea17e6f2f92419c5a52ffa35f44..e9f3b3e4bbf45805d5288ad0d3ee03243c2a1af0 100644 (file)
@@ -529,7 +529,8 @@ static void dev_dax_release(struct device *dev)
        struct dax_region *dax_region = dev_dax->region;
        struct dax_device *dax_dev = dev_dax->dax_dev;
 
-       ida_simple_remove(&dax_region->ida, dev_dax->id);
+       if (dev_dax->id >= 0)
+               ida_simple_remove(&dax_region->ida, dev_dax->id);
        dax_region_put(dax_region);
        put_dax(dax_dev);
        kfree(dev_dax);
@@ -559,7 +560,7 @@ static void unregister_dev_dax(void *dev)
 }
 
 struct dev_dax *devm_create_dev_dax(struct dax_region *dax_region,
-               struct resource *res, int count)
+               int id, struct resource *res, int count)
 {
        struct device *parent = dax_region->dev;
        struct dax_device *dax_dev;
@@ -567,7 +568,10 @@ struct dev_dax *devm_create_dev_dax(struct dax_region *dax_region,
        struct inode *inode;
        struct device *dev;
        struct cdev *cdev;
-       int rc = 0, i;
+       int rc, i;
+
+       if (!count)
+               return ERR_PTR(-EINVAL);
 
        dev_dax = kzalloc(sizeof(*dev_dax) + sizeof(*res) * count, GFP_KERNEL);
        if (!dev_dax)
@@ -587,10 +591,16 @@ struct dev_dax *devm_create_dev_dax(struct dax_region *dax_region,
        if (i < count)
                goto err_id;
 
-       dev_dax->id = ida_simple_get(&dax_region->ida, 0, 0, GFP_KERNEL);
-       if (dev_dax->id < 0) {
-               rc = dev_dax->id;
-               goto err_id;
+       if (id < 0) {
+               id = ida_simple_get(&dax_region->ida, 0, 0, GFP_KERNEL);
+               dev_dax->id = id;
+               if (id < 0) {
+                       rc = id;
+                       goto err_id;
+               }
+       } else {
+               /* region provider owns @id lifetime */
+               dev_dax->id = -1;
        }
 
        /*
@@ -598,8 +608,10 @@ struct dev_dax *devm_create_dev_dax(struct dax_region *dax_region,
         * device outside of mmap of the resulting character device.
         */
        dax_dev = alloc_dax(dev_dax, NULL, NULL);
-       if (!dax_dev)
+       if (!dax_dev) {
+               rc = -ENOMEM;
                goto err_dax;
+       }
 
        /* from here on we're committed to teardown via dax_dev_release() */
        dev = &dev_dax->dev;
@@ -620,7 +632,7 @@ struct dev_dax *devm_create_dev_dax(struct dax_region *dax_region,
        dev->parent = parent;
        dev->groups = dax_attribute_groups;
        dev->release = dev_dax_release;
-       dev_set_name(dev, "dax%d.%d", dax_region->id, dev_dax->id);
+       dev_set_name(dev, "dax%d.%d", dax_region->id, id);
 
        rc = cdev_device_add(cdev, dev);
        if (rc) {
@@ -636,7 +648,8 @@ struct dev_dax *devm_create_dev_dax(struct dax_region *dax_region,
        return dev_dax;
 
  err_dax:
-       ida_simple_remove(&dax_region->ida, dev_dax->id);
+       if (dev_dax->id >= 0)
+               ida_simple_remove(&dax_region->ida, dev_dax->id);
  err_id:
        kfree(dev_dax);
 
index 9f2a0b4fd8012c05b79a561ee4c2711e64c17fa5..8d8c852ba8f209c5118987aa2dbb98cf3290d213 100644 (file)
@@ -58,13 +58,12 @@ static void dax_pmem_percpu_kill(void *data)
 
 static int dax_pmem_probe(struct device *dev)
 {
-       int rc;
        void *addr;
        struct resource res;
+       int rc, id, region_id;
        struct nd_pfn_sb *pfn_sb;
        struct dev_dax *dev_dax;
        struct dax_pmem *dax_pmem;
-       struct nd_region *nd_region;
        struct nd_namespace_io *nsio;
        struct dax_region *dax_region;
        struct nd_namespace_common *ndns;
@@ -123,14 +122,17 @@ static int dax_pmem_probe(struct device *dev)
        /* adjust the dax_region resource to the start of data */
        res.start += le64_to_cpu(pfn_sb->dataoff);
 
-       nd_region = to_nd_region(dev->parent);
-       dax_region = alloc_dax_region(dev, nd_region->id, &res,
+       rc = sscanf(dev_name(&ndns->dev), "namespace%d.%d", &region_id, &id);
+       if (rc != 2)
+               return -EINVAL;
+
+       dax_region = alloc_dax_region(dev, region_id, &res,
                        le32_to_cpu(pfn_sb->align), addr, PFN_DEV|PFN_MAP);
        if (!dax_region)
                return -ENOMEM;
 
        /* TODO: support for subdividing a dax region... */
-       dev_dax = devm_create_dev_dax(dax_region, &res, 1);
+       dev_dax = devm_create_dev_dax(dax_region, id, &res, 1);
 
        /* child dev_dax instances now own the lifetime of the dax_region */
        dax_region_put(dax_region);
index 41b39464ded87f6ee3a4b0b302e0df52feddc520..501e16a9227dc001df41d993aafb6fb092116752 100644 (file)
@@ -2732,6 +2732,9 @@ static int hidpp_initialize_battery(struct hidpp_device *hidpp)
                                     hidpp_battery_props,
                                     sizeof(hidpp_battery_props),
                                     GFP_KERNEL);
+       if (!battery_props)
+               return -ENOMEM;
+
        num_battery_props = ARRAY_SIZE(hidpp_battery_props) - 2;
 
        if (hidpp->capabilities & HIDPP_CAPABILITY_BATTERY_MILEAGE)
index f3e35e7a189d30aba1b6619ddba328cbec75a836..aff20f4b6d97ead09453b303eaf4ac3ac94e1628 100644 (file)
@@ -620,16 +620,6 @@ static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi,
        return 0;
 }
 
-static int mt_touch_input_mapped(struct hid_device *hdev, struct hid_input *hi,
-               struct hid_field *field, struct hid_usage *usage,
-               unsigned long **bit, int *max)
-{
-       if (usage->type == EV_KEY || usage->type == EV_ABS)
-               set_bit(usage->type, hi->input->evbit);
-
-       return -1;
-}
-
 static int mt_compute_slot(struct mt_device *td, struct input_dev *input)
 {
        __s32 quirks = td->mtclass.quirks;
@@ -969,8 +959,10 @@ static int mt_input_mapped(struct hid_device *hdev, struct hid_input *hi,
                return 0;
 
        if (field->application == HID_DG_TOUCHSCREEN ||
-           field->application == HID_DG_TOUCHPAD)
-               return mt_touch_input_mapped(hdev, hi, field, usage, bit, max);
+           field->application == HID_DG_TOUCHPAD) {
+               /* We own these mappings, tell hid-input to ignore them */
+               return -1;
+       }
 
        /* let hid-core decide for the others */
        return 0;
index a6cb379a4ebcb3060c93eb959aa3071d45f78b37..01236cef7bfb1affe07e4214cf6d8baf6ca2a2a1 100644 (file)
@@ -268,6 +268,7 @@ int rdma_translate_ip(const struct sockaddr *addr,
                        return ret;
 
                ret = rdma_copy_addr(dev_addr, dev, NULL);
+               dev_addr->bound_dev_if = dev->ifindex;
                if (vlan_id)
                        *vlan_id = rdma_vlan_dev_vlan_id(dev);
                dev_put(dev);
@@ -280,6 +281,7 @@ int rdma_translate_ip(const struct sockaddr *addr,
                                          &((const struct sockaddr_in6 *)addr)->sin6_addr,
                                          dev, 1)) {
                                ret = rdma_copy_addr(dev_addr, dev, NULL);
+                               dev_addr->bound_dev_if = dev->ifindex;
                                if (vlan_id)
                                        *vlan_id = rdma_vlan_dev_vlan_id(dev);
                                break;
@@ -405,10 +407,10 @@ static int addr4_resolve(struct sockaddr_in *src_in,
        fl4.saddr = src_ip;
        fl4.flowi4_oif = addr->bound_dev_if;
        rt = ip_route_output_key(addr->net, &fl4);
-       if (IS_ERR(rt)) {
-               ret = PTR_ERR(rt);
-               goto out;
-       }
+       ret = PTR_ERR_OR_ZERO(rt);
+       if (ret)
+               return ret;
+
        src_in->sin_family = AF_INET;
        src_in->sin_addr.s_addr = fl4.saddr;
 
@@ -423,8 +425,6 @@ static int addr4_resolve(struct sockaddr_in *src_in,
 
        *prt = rt;
        return 0;
-out:
-       return ret;
 }
 
 #if IS_ENABLED(CONFIG_IPV6)
@@ -509,6 +509,11 @@ static int addr_resolve(struct sockaddr *src_in,
        struct dst_entry *dst;
        int ret;
 
+       if (!addr->net) {
+               pr_warn_ratelimited("%s: missing namespace\n", __func__);
+               return -EINVAL;
+       }
+
        if (src_in->sa_family == AF_INET) {
                struct rtable *rt = NULL;
                const struct sockaddr_in *dst_in4 =
@@ -522,8 +527,12 @@ static int addr_resolve(struct sockaddr *src_in,
                if (resolve_neigh)
                        ret = addr_resolve_neigh(&rt->dst, dst_in, addr, seq);
 
-               ndev = rt->dst.dev;
-               dev_hold(ndev);
+               if (addr->bound_dev_if) {
+                       ndev = dev_get_by_index(addr->net, addr->bound_dev_if);
+               } else {
+                       ndev = rt->dst.dev;
+                       dev_hold(ndev);
+               }
 
                ip_rt_put(rt);
        } else {
@@ -539,14 +548,27 @@ static int addr_resolve(struct sockaddr *src_in,
                if (resolve_neigh)
                        ret = addr_resolve_neigh(dst, dst_in, addr, seq);
 
-               ndev = dst->dev;
-               dev_hold(ndev);
+               if (addr->bound_dev_if) {
+                       ndev = dev_get_by_index(addr->net, addr->bound_dev_if);
+               } else {
+                       ndev = dst->dev;
+                       dev_hold(ndev);
+               }
 
                dst_release(dst);
        }
 
-       addr->bound_dev_if = ndev->ifindex;
-       addr->net = dev_net(ndev);
+       if (ndev->flags & IFF_LOOPBACK) {
+               ret = rdma_translate_ip(dst_in, addr, NULL);
+               /*
+                * Put the loopback device and get the translated
+                * device instead.
+                */
+               dev_put(ndev);
+               ndev = dev_get_by_index(addr->net, addr->bound_dev_if);
+       } else {
+               addr->bound_dev_if = ndev->ifindex;
+       }
        dev_put(ndev);
 
        return ret;
index 31bb82d8ecd7f19bbee90bd95a83cec7fe5abca7..11aff923b633f9eb5329993dab8e5db445d31aa8 100644 (file)
@@ -623,22 +623,11 @@ static inline int cma_validate_port(struct ib_device *device, u8 port,
        if ((dev_type != ARPHRD_INFINIBAND) && rdma_protocol_ib(device, port))
                return ret;
 
-       if (dev_type == ARPHRD_ETHER && rdma_protocol_roce(device, port)) {
+       if (dev_type == ARPHRD_ETHER && rdma_protocol_roce(device, port))
                ndev = dev_get_by_index(&init_net, bound_if_index);
-               if (ndev && ndev->flags & IFF_LOOPBACK) {
-                       pr_info("detected loopback device\n");
-                       dev_put(ndev);
-
-                       if (!device->get_netdev)
-                               return -EOPNOTSUPP;
-
-                       ndev = device->get_netdev(device, port);
-                       if (!ndev)
-                               return -ENODEV;
-               }
-       } else {
+       else
                gid_type = IB_GID_TYPE_IB;
-       }
+
 
        ret = ib_find_cached_gid_by_port(device, gid, gid_type, port,
                                         ndev, NULL);
@@ -2569,21 +2558,6 @@ static int cma_resolve_iboe_route(struct rdma_id_private *id_priv)
                        goto err2;
                }
 
-               if (ndev->flags & IFF_LOOPBACK) {
-                       dev_put(ndev);
-                       if (!id_priv->id.device->get_netdev) {
-                               ret = -EOPNOTSUPP;
-                               goto err2;
-                       }
-
-                       ndev = id_priv->id.device->get_netdev(id_priv->id.device,
-                                                             id_priv->id.port_num);
-                       if (!ndev) {
-                               ret = -ENODEV;
-                               goto err2;
-                       }
-               }
-
                supported_gids = roce_gid_type_mask_support(id_priv->id.device,
                                                            id_priv->id.port_num);
                gid_type = cma_route_gid_type(addr->dev_addr.network,
index db958d3207efc9e13aa1ae2d05fbadce2732c0cd..94a9eefb3cfcad894d13b400a9d3a2281773b5b0 100644 (file)
@@ -42,6 +42,8 @@
 #include <rdma/ib_cache.h>
 #include <rdma/ib_addr.h>
 
+static struct workqueue_struct *gid_cache_wq;
+
 enum gid_op_type {
        GID_DEL = 0,
        GID_ADD
@@ -560,7 +562,7 @@ static int netdevice_queue_work(struct netdev_event_work_cmd *cmds,
        }
        INIT_WORK(&ndev_work->work, netdevice_event_work_handler);
 
-       queue_work(ib_wq, &ndev_work->work);
+       queue_work(gid_cache_wq, &ndev_work->work);
 
        return NOTIFY_DONE;
 }
@@ -693,7 +695,7 @@ static int addr_event(struct notifier_block *this, unsigned long event,
        dev_hold(ndev);
        work->gid_attr.ndev   = ndev;
 
-       queue_work(ib_wq, &work->work);
+       queue_work(gid_cache_wq, &work->work);
 
        return NOTIFY_DONE;
 }
@@ -740,6 +742,10 @@ static struct notifier_block nb_inet6addr = {
 
 int __init roce_gid_mgmt_init(void)
 {
+       gid_cache_wq = alloc_ordered_workqueue("gid-cache-wq", 0);
+       if (!gid_cache_wq)
+               return -ENOMEM;
+
        register_inetaddr_notifier(&nb_inetaddr);
        if (IS_ENABLED(CONFIG_IPV6))
                register_inet6addr_notifier(&nb_inet6addr);
@@ -764,4 +770,5 @@ void __exit roce_gid_mgmt_cleanup(void)
         * ib-core is removed, all physical devices have been removed,
         * so no issue with remaining hardware contexts.
         */
+       destroy_workqueue(gid_cache_wq);
 }
index 8ba9bfb073d17c3025206fe66995547433c6a9a8..3f55d18a379145a45ef624e03b8ca2b8cbe5343f 100644 (file)
@@ -2005,28 +2005,13 @@ static int modify_qp(struct ib_uverbs_file *file,
        rdma_ah_set_port_num(&attr->alt_ah_attr,
                             cmd->base.alt_dest.port_num);
 
-       if (qp->real_qp == qp) {
-               if (cmd->base.attr_mask & IB_QP_AV) {
-                       ret = ib_resolve_eth_dmac(qp->device, &attr->ah_attr);
-                       if (ret)
-                               goto release_qp;
-               }
-               ret = ib_security_modify_qp(qp,
-                                           attr,
-                                           modify_qp_mask(qp->qp_type,
-                                                          cmd->base.attr_mask),
-                                           udata);
-       } else {
-               ret = ib_security_modify_qp(qp,
-                                           attr,
-                                           modify_qp_mask(qp->qp_type,
-                                                          cmd->base.attr_mask),
-                                           NULL);
-       }
+       ret = ib_modify_qp_with_udata(qp, attr,
+                                     modify_qp_mask(qp->qp_type,
+                                                    cmd->base.attr_mask),
+                                     udata);
 
 release_qp:
        uobj_put_obj_read(qp);
-
 out:
        kfree(attr);
 
index c973a83c898b487710600f4e4f6441c99595ca6c..fb98ed67d5bc684b8cc0b941d7140986b95aa99b 100644 (file)
@@ -452,6 +452,19 @@ int ib_get_gids_from_rdma_hdr(const union rdma_network_hdr *hdr,
 }
 EXPORT_SYMBOL(ib_get_gids_from_rdma_hdr);
 
+/*
+ * This function creates ah from the incoming packet.
+ * Incoming packet has dgid of the receiver node on which this code is
+ * getting executed and, sgid contains the GID of the sender.
+ *
+ * When resolving mac address of destination, the arrived dgid is used
+ * as sgid and, sgid is used as dgid because sgid contains destinations
+ * GID whom to respond to.
+ *
+ * This is why when calling rdma_addr_find_l2_eth_by_grh() function, the
+ * position of arguments dgid and sgid do not match the order of the
+ * parameters.
+ */
 int ib_init_ah_from_wc(struct ib_device *device, u8 port_num,
                       const struct ib_wc *wc, const struct ib_grh *grh,
                       struct rdma_ah_attr *ah_attr)
@@ -507,11 +520,6 @@ int ib_init_ah_from_wc(struct ib_device *device, u8 port_num,
                }
 
                resolved_dev = dev_get_by_index(&init_net, if_index);
-               if (resolved_dev->flags & IFF_LOOPBACK) {
-                       dev_put(resolved_dev);
-                       resolved_dev = idev;
-                       dev_hold(resolved_dev);
-               }
                rcu_read_lock();
                if (resolved_dev != idev && !rdma_is_upper_dev_rcu(idev,
                                                                   resolved_dev))
@@ -887,6 +895,7 @@ static const struct {
 } qp_state_table[IB_QPS_ERR + 1][IB_QPS_ERR + 1] = {
        [IB_QPS_RESET] = {
                [IB_QPS_RESET] = { .valid = 1 },
+               [IB_QPS_ERR] =   { .valid = 1 },
                [IB_QPS_INIT]  = {
                        .valid = 1,
                        .req_param = {
@@ -1268,20 +1277,36 @@ out:
 }
 EXPORT_SYMBOL(ib_resolve_eth_dmac);
 
-int ib_modify_qp(struct ib_qp *qp,
-                struct ib_qp_attr *qp_attr,
-                int qp_attr_mask)
+/**
+ * ib_modify_qp_with_udata - Modifies the attributes for the specified QP.
+ * @qp: The QP to modify.
+ * @attr: On input, specifies the QP attributes to modify.  On output,
+ *   the current values of selected QP attributes are returned.
+ * @attr_mask: A bit-mask used to specify which attributes of the QP
+ *   are being modified.
+ * @udata: pointer to user's input output buffer information
+ *   are being modified.
+ * It returns 0 on success and returns appropriate error code on error.
+ */
+int ib_modify_qp_with_udata(struct ib_qp *qp, struct ib_qp_attr *attr,
+                           int attr_mask, struct ib_udata *udata)
 {
+       int ret;
 
-       if (qp_attr_mask & IB_QP_AV) {
-               int ret;
-
-               ret = ib_resolve_eth_dmac(qp->device, &qp_attr->ah_attr);
+       if (attr_mask & IB_QP_AV) {
+               ret = ib_resolve_eth_dmac(qp->device, &attr->ah_attr);
                if (ret)
                        return ret;
        }
+       return ib_security_modify_qp(qp, attr, attr_mask, udata);
+}
+EXPORT_SYMBOL(ib_modify_qp_with_udata);
 
-       return ib_security_modify_qp(qp->real_qp, qp_attr, qp_attr_mask, NULL);
+int ib_modify_qp(struct ib_qp *qp,
+                struct ib_qp_attr *qp_attr,
+                int qp_attr_mask)
+{
+       return ib_modify_qp_with_udata(qp, qp_attr, qp_attr_mask, NULL);
 }
 EXPORT_SYMBOL(ib_modify_qp);
 
index 2ba00b89df6a046bba536cfe889c373d9063ced0..94b54850ec75b7273eb63b961ffe7ebfbc0ee5c5 100644 (file)
@@ -12847,7 +12847,12 @@ static void remap_intr(struct hfi1_devdata *dd, int isrc, int msix_intr)
        /* clear from the handled mask of the general interrupt */
        m = isrc / 64;
        n = isrc % 64;
-       dd->gi_mask[m] &= ~((u64)1 << n);
+       if (likely(m < CCE_NUM_INT_CSRS)) {
+               dd->gi_mask[m] &= ~((u64)1 << n);
+       } else {
+               dd_dev_err(dd, "remap interrupt err\n");
+               return;
+       }
 
        /* direct the chip source to the given MSI-X interrupt */
        m = isrc / 8;
index 650305cc037306923e5e742c02f7977e672a70f9..1a7af9f60c137f916a125588318a182cf535ac01 100644 (file)
@@ -647,18 +647,17 @@ void qp_iter_print(struct seq_file *s, struct qp_iter *iter)
                   qp->pid);
 }
 
-void *qp_priv_alloc(struct rvt_dev_info *rdi, struct rvt_qp *qp,
-                   gfp_t gfp)
+void *qp_priv_alloc(struct rvt_dev_info *rdi, struct rvt_qp *qp)
 {
        struct hfi1_qp_priv *priv;
 
-       priv = kzalloc_node(sizeof(*priv), gfp, rdi->dparms.node);
+       priv = kzalloc_node(sizeof(*priv), GFP_KERNEL, rdi->dparms.node);
        if (!priv)
                return ERR_PTR(-ENOMEM);
 
        priv->owner = qp;
 
-       priv->s_ahg = kzalloc_node(sizeof(*priv->s_ahg), gfp,
+       priv->s_ahg = kzalloc_node(sizeof(*priv->s_ahg), GFP_KERNEL,
                                   rdi->dparms.node);
        if (!priv->s_ahg) {
                kfree(priv);
index 1eb9cd7b8c1973da834ed36ea42e7ae61a524c17..6fe542b6a92751863cd6385be0fe0654a346f08f 100644 (file)
@@ -123,8 +123,7 @@ void hfi1_migrate_qp(struct rvt_qp *qp);
 /*
  * Functions provided by hfi1 driver for rdmavt to use
  */
-void *qp_priv_alloc(struct rvt_dev_info *rdi, struct rvt_qp *qp,
-                   gfp_t gfp);
+void *qp_priv_alloc(struct rvt_dev_info *rdi, struct rvt_qp *qp);
 void qp_priv_free(struct rvt_dev_info *rdi, struct rvt_qp *qp);
 unsigned free_all_qps(struct rvt_dev_info *rdi);
 void notify_qp_reset(struct rvt_qp *qp);
index 37d5d29597a449d23bf34587024b83e4c55bb657..23fad6d969440bd2bd50a0c8b0dbafe8a92f4ae9 100644 (file)
@@ -228,14 +228,14 @@ int hns_roce_v1_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
                        switch (wr->opcode) {
                        case IB_WR_RDMA_READ:
                                ps_opcode = HNS_ROCE_WQE_OPCODE_RDMA_READ;
-                               set_raddr_seg(wqe, atomic_wr(wr)->remote_addr,
-                                             atomic_wr(wr)->rkey);
+                               set_raddr_seg(wqe,  rdma_wr(wr)->remote_addr,
+                                              rdma_wr(wr)->rkey);
                                break;
                        case IB_WR_RDMA_WRITE:
                        case IB_WR_RDMA_WRITE_WITH_IMM:
                                ps_opcode = HNS_ROCE_WQE_OPCODE_RDMA_WRITE;
-                               set_raddr_seg(wqe, atomic_wr(wr)->remote_addr,
-                                             atomic_wr(wr)->rkey);
+                               set_raddr_seg(wqe,  rdma_wr(wr)->remote_addr,
+                                             rdma_wr(wr)->rkey);
                                break;
                        case IB_WR_SEND:
                        case IB_WR_SEND_WITH_INV:
@@ -661,9 +661,11 @@ static int hns_roce_v1_rsv_lp_qp(struct hns_roce_dev *hr_dev)
        union ib_gid dgid;
        u64 subnet_prefix;
        int attr_mask = 0;
-       int i;
+       int i, j;
        int ret;
+       u8 queue_en[HNS_ROCE_V1_RESV_QP] = { 0 };
        u8 phy_port;
+       u8 port = 0;
        u8 sl;
 
        priv = (struct hns_roce_v1_priv *)hr_dev->hw->priv;
@@ -709,11 +711,27 @@ static int hns_roce_v1_rsv_lp_qp(struct hns_roce_dev *hr_dev)
        attr.rnr_retry          = 7;
        attr.timeout            = 0x12;
        attr.path_mtu           = IB_MTU_256;
+       attr.ah_attr.type       = RDMA_AH_ATTR_TYPE_ROCE;
        rdma_ah_set_grh(&attr.ah_attr, NULL, 0, 0, 1, 0);
        rdma_ah_set_static_rate(&attr.ah_attr, 3);
 
        subnet_prefix = cpu_to_be64(0xfe80000000000000LL);
        for (i = 0; i < HNS_ROCE_V1_RESV_QP; i++) {
+               phy_port = (i >= HNS_ROCE_MAX_PORTS) ? (i - 2) :
+                               (i % HNS_ROCE_MAX_PORTS);
+               sl = i / HNS_ROCE_MAX_PORTS;
+
+               for (j = 0; j < caps->num_ports; j++) {
+                       if (hr_dev->iboe.phy_port[j] == phy_port) {
+                               queue_en[i] = 1;
+                               port = j;
+                               break;
+                       }
+               }
+
+               if (!queue_en[i])
+                       continue;
+
                free_mr->mr_free_qp[i] = hns_roce_v1_create_lp_qp(hr_dev, pd);
                if (IS_ERR(free_mr->mr_free_qp[i])) {
                        dev_err(dev, "Create loop qp failed!\n");
@@ -721,15 +739,7 @@ static int hns_roce_v1_rsv_lp_qp(struct hns_roce_dev *hr_dev)
                }
                hr_qp = free_mr->mr_free_qp[i];
 
-               sl = i / caps->num_ports;
-
-               if (caps->num_ports == HNS_ROCE_MAX_PORTS)
-                       phy_port = (i >= HNS_ROCE_MAX_PORTS) ? (i - 2) :
-                               (i % caps->num_ports);
-               else
-                       phy_port = i % caps->num_ports;
-
-               hr_qp->port             = phy_port + 1;
+               hr_qp->port             = port;
                hr_qp->phy_port         = phy_port;
                hr_qp->ibqp.qp_type     = IB_QPT_RC;
                hr_qp->ibqp.device      = &hr_dev->ib_dev;
@@ -739,23 +749,22 @@ static int hns_roce_v1_rsv_lp_qp(struct hns_roce_dev *hr_dev)
                hr_qp->ibqp.recv_cq     = cq;
                hr_qp->ibqp.send_cq     = cq;
 
-               rdma_ah_set_port_num(&attr.ah_attr, phy_port + 1);
-               rdma_ah_set_sl(&attr.ah_attr, phy_port + 1);
-               attr.port_num           = phy_port + 1;
+               rdma_ah_set_port_num(&attr.ah_attr, port + 1);
+               rdma_ah_set_sl(&attr.ah_attr, sl);
+               attr.port_num           = port + 1;
 
                attr.dest_qp_num        = hr_qp->qpn;
                memcpy(rdma_ah_retrieve_dmac(&attr.ah_attr),
-                      hr_dev->dev_addr[phy_port],
+                      hr_dev->dev_addr[port],
                       MAC_ADDR_OCTET_NUM);
 
                memcpy(&dgid.raw, &subnet_prefix, sizeof(u64));
-               memcpy(&dgid.raw[8], hr_dev->dev_addr[phy_port], 3);
-               memcpy(&dgid.raw[13], hr_dev->dev_addr[phy_port] + 3, 3);
+               memcpy(&dgid.raw[8], hr_dev->dev_addr[port], 3);
+               memcpy(&dgid.raw[13], hr_dev->dev_addr[port] + 3, 3);
                dgid.raw[11] = 0xff;
                dgid.raw[12] = 0xfe;
                dgid.raw[8] ^= 2;
                rdma_ah_set_dgid_raw(&attr.ah_attr, dgid.raw);
-               attr_mask |= IB_QP_PORT;
 
                ret = hr_dev->hw->modify_qp(&hr_qp->ibqp, &attr, attr_mask,
                                            IB_QPS_RESET, IB_QPS_INIT);
@@ -812,6 +821,9 @@ static void hns_roce_v1_release_lp_qp(struct hns_roce_dev *hr_dev)
 
        for (i = 0; i < HNS_ROCE_V1_RESV_QP; i++) {
                hr_qp = free_mr->mr_free_qp[i];
+               if (!hr_qp)
+                       continue;
+
                ret = hns_roce_v1_destroy_qp(&hr_qp->ibqp);
                if (ret)
                        dev_err(dev, "Destroy qp %d for mr free failed(%d)!\n",
@@ -963,7 +975,7 @@ static void hns_roce_v1_mr_free_work_fn(struct work_struct *work)
                msecs_to_jiffies(HNS_ROCE_V1_FREE_MR_TIMEOUT_MSECS) + jiffies;
        int i;
        int ret;
-       int ne;
+       int ne = 0;
 
        mr_work = container_of(work, struct hns_roce_mr_free_work, work);
        hr_mr = (struct hns_roce_mr *)mr_work->mr;
@@ -976,6 +988,10 @@ static void hns_roce_v1_mr_free_work_fn(struct work_struct *work)
 
        for (i = 0; i < HNS_ROCE_V1_RESV_QP; i++) {
                hr_qp = free_mr->mr_free_qp[i];
+               if (!hr_qp)
+                       continue;
+               ne++;
+
                ret = hns_roce_v1_send_lp_wqe(hr_qp);
                if (ret) {
                        dev_err(dev,
@@ -985,7 +1001,6 @@ static void hns_roce_v1_mr_free_work_fn(struct work_struct *work)
                }
        }
 
-       ne = HNS_ROCE_V1_RESV_QP;
        do {
                ret = hns_roce_v1_poll_cq(&mr_free_cq->ib_cq, ne, wc);
                if (ret < 0) {
@@ -995,7 +1010,8 @@ static void hns_roce_v1_mr_free_work_fn(struct work_struct *work)
                        goto free_work;
                }
                ne -= ret;
-               msleep(HNS_ROCE_V1_FREE_MR_WAIT_VALUE);
+               usleep_range(HNS_ROCE_V1_FREE_MR_WAIT_VALUE * 1000,
+                            (1 + HNS_ROCE_V1_FREE_MR_WAIT_VALUE) * 1000);
        } while (ne && time_before_eq(jiffies, end));
 
        if (ne != 0)
@@ -2181,7 +2197,7 @@ static int hns_roce_v1_poll_one(struct hns_roce_cq *hr_cq,
                }
                wc->wr_id = wq->wrid[wq->tail & (wq->wqe_cnt - 1)];
                ++wq->tail;
-               } else {
+       } else {
                /* RQ conrespond to CQE */
                wc->byte_len = le32_to_cpu(cqe->byte_cnt);
                opcode = roce_get_field(cqe->cqe_byte_4,
@@ -3533,10 +3549,12 @@ static int check_qp_db_process_status(struct hns_roce_dev *hr_dev,
                                        old_cnt = roce_get_field(old_send,
                                        ROCEE_SDB_SEND_PTR_SDB_SEND_PTR_M,
                                        ROCEE_SDB_SEND_PTR_SDB_SEND_PTR_S);
-                                       if (cur_cnt - old_cnt > SDB_ST_CMP_VAL)
+                                       if (cur_cnt - old_cnt >
+                                           SDB_ST_CMP_VAL) {
                                                success_flags = 1;
-                                       else {
-                                           send_ptr = roce_get_field(old_send,
+                                       } else {
+                                               send_ptr =
+                                                       roce_get_field(old_send,
                                            ROCEE_SDB_SEND_PTR_SDB_SEND_PTR_M,
                                            ROCEE_SDB_SEND_PTR_SDB_SEND_PTR_S) +
                                            roce_get_field(sdb_retry_cnt,
@@ -3641,6 +3659,7 @@ static void hns_roce_v1_destroy_qp_work_fn(struct work_struct *work)
        struct hns_roce_dev *hr_dev;
        struct hns_roce_qp *hr_qp;
        struct device *dev;
+       unsigned long qpn;
        int ret;
 
        qp_work_entry = container_of(work, struct hns_roce_qp_work, work);
@@ -3648,8 +3667,9 @@ static void hns_roce_v1_destroy_qp_work_fn(struct work_struct *work)
        dev = &hr_dev->pdev->dev;
        priv = (struct hns_roce_v1_priv *)hr_dev->hw->priv;
        hr_qp = qp_work_entry->qp;
+       qpn = hr_qp->qpn;
 
-       dev_dbg(dev, "Schedule destroy QP(0x%lx) work.\n", hr_qp->qpn);
+       dev_dbg(dev, "Schedule destroy QP(0x%lx) work.\n", qpn);
 
        qp_work_entry->sche_cnt++;
 
@@ -3660,7 +3680,7 @@ static void hns_roce_v1_destroy_qp_work_fn(struct work_struct *work)
                                         &qp_work_entry->db_wait_stage);
        if (ret) {
                dev_err(dev, "Check QP(0x%lx) db process status failed!\n",
-                       hr_qp->qpn);
+                       qpn);
                return;
        }
 
@@ -3674,7 +3694,7 @@ static void hns_roce_v1_destroy_qp_work_fn(struct work_struct *work)
        ret = hns_roce_v1_modify_qp(&hr_qp->ibqp, NULL, 0, hr_qp->state,
                                    IB_QPS_RESET);
        if (ret) {
-               dev_err(dev, "Modify QP(0x%lx) to RST failed!\n", hr_qp->qpn);
+               dev_err(dev, "Modify QP(0x%lx) to RST failed!\n", qpn);
                return;
        }
 
@@ -3683,14 +3703,14 @@ static void hns_roce_v1_destroy_qp_work_fn(struct work_struct *work)
 
        if (hr_qp->ibqp.qp_type == IB_QPT_RC) {
                /* RC QP, release QPN */
-               hns_roce_release_range_qp(hr_dev, hr_qp->qpn, 1);
+               hns_roce_release_range_qp(hr_dev, qpn, 1);
                kfree(hr_qp);
        } else
                kfree(hr_to_hr_sqp(hr_qp));
 
        kfree(qp_work_entry);
 
-       dev_dbg(dev, "Accomplished destroy QP(0x%lx) work.\n", hr_qp->qpn);
+       dev_dbg(dev, "Accomplished destroy QP(0x%lx) work.\n", qpn);
 }
 
 int hns_roce_v1_destroy_qp(struct ib_qp *ibqp)
index c3b41f95e70a5f1c39e89d91e48653fc05e2b20a..d9777b662eba94ed6d917b262f073f911b073059 100644 (file)
@@ -125,8 +125,6 @@ static int handle_en_event(struct hns_roce_dev *hr_dev, u8 port,
                return -ENODEV;
        }
 
-       spin_lock_bh(&hr_dev->iboe.lock);
-
        switch (event) {
        case NETDEV_UP:
        case NETDEV_CHANGE:
@@ -144,7 +142,6 @@ static int handle_en_event(struct hns_roce_dev *hr_dev, u8 port,
                break;
        }
 
-       spin_unlock_bh(&hr_dev->iboe.lock);
        return 0;
 }
 
index 4f5a143fc0a7229a703d0ba99a6fdd1cddb00313..ff931c580557b18cdecab6d86d00297e6c7993ff 100644 (file)
@@ -102,7 +102,7 @@ static int mlx4_ib_alloc_cq_buf(struct mlx4_ib_dev *dev, struct mlx4_ib_cq_buf *
        int err;
 
        err = mlx4_buf_alloc(dev->dev, nent * dev->dev->caps.cqe_size,
-                            PAGE_SIZE * 2, &buf->buf, GFP_KERNEL);
+                            PAGE_SIZE * 2, &buf->buf);
 
        if (err)
                goto out;
@@ -113,7 +113,7 @@ static int mlx4_ib_alloc_cq_buf(struct mlx4_ib_dev *dev, struct mlx4_ib_cq_buf *
        if (err)
                goto err_buf;
 
-       err = mlx4_buf_write_mtt(dev->dev, &buf->mtt, &buf->buf, GFP_KERNEL);
+       err = mlx4_buf_write_mtt(dev->dev, &buf->mtt, &buf->buf);
        if (err)
                goto err_mtt;
 
@@ -219,7 +219,7 @@ struct ib_cq *mlx4_ib_create_cq(struct ib_device *ibdev,
 
                uar = &to_mucontext(context)->uar;
        } else {
-               err = mlx4_db_alloc(dev->dev, &cq->db, 1, GFP_KERNEL);
+               err = mlx4_db_alloc(dev->dev, &cq->db, 1);
                if (err)
                        goto err_cq;
 
index 75b2f7d4cd95577814a3b9031aff4c0cebf56fa4..d1b43cbbfea7795418d4e2dffb5acaf454552c85 100644 (file)
@@ -1155,7 +1155,7 @@ static void mlx4_ib_disassociate_ucontext(struct ib_ucontext *ibcontext)
                         * call to mlx4_ib_vma_close.
                         */
                        put_task_struct(owning_process);
-                       msleep(1);
+                       usleep_range(1000, 2000);
                        owning_process = get_pid_task(ibcontext->tgid,
                                                      PIDTYPE_PID);
                        if (!owning_process ||
index 3405e947dc1ebb420b2e2aa3104e1a2ea92485f8..b73f89700ef9eaee928487b374491e863eb4444e 100644 (file)
@@ -1091,7 +1091,7 @@ static void _mlx4_ib_mcg_port_cleanup(struct mlx4_ib_demux_ctx *ctx, int destroy
                if (!count)
                        break;
 
-               msleep(1);
+               usleep_range(1000, 2000);
        } while (time_after(end, jiffies));
 
        flush_workqueue(ctx->mcg_wq);
index c2b9cbf4da050e22afee4251079f7eece418416a..9db82e67e9591a5f56a540da8b8c96984714cbae 100644 (file)
@@ -185,7 +185,6 @@ enum mlx4_ib_qp_flags {
        MLX4_IB_QP_LSO = IB_QP_CREATE_IPOIB_UD_LSO,
        MLX4_IB_QP_BLOCK_MULTICAST_LOOPBACK = IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK,
        MLX4_IB_QP_NETIF = IB_QP_CREATE_NETIF_QP,
-       MLX4_IB_QP_CREATE_USE_GFP_NOIO = IB_QP_CREATE_USE_GFP_NOIO,
 
        /* Mellanox specific flags start from IB_QP_CREATE_RESERVED_START */
        MLX4_IB_ROCE_V2_GSI_QP = MLX4_IB_QP_CREATE_ROCE_V2_GSI,
index 996e9058e515adf924eb23fd9ef10606ab74342a..75c0e6c5dd5691a2d57f21a80be80e29fb07b706 100644 (file)
@@ -634,8 +634,8 @@ static void mlx4_ib_free_qp_counter(struct mlx4_ib_dev *dev,
 
 static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
                            struct ib_qp_init_attr *init_attr,
-                           struct ib_udata *udata, int sqpn, struct mlx4_ib_qp **caller_qp,
-                           gfp_t gfp)
+                           struct ib_udata *udata, int sqpn,
+                           struct mlx4_ib_qp **caller_qp)
 {
        int qpn;
        int err;
@@ -691,14 +691,14 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
                if (qp_type == MLX4_IB_QPT_SMI || qp_type == MLX4_IB_QPT_GSI ||
                    (qp_type & (MLX4_IB_QPT_PROXY_SMI | MLX4_IB_QPT_PROXY_SMI_OWNER |
                                MLX4_IB_QPT_PROXY_GSI | MLX4_IB_QPT_TUN_SMI_OWNER))) {
-                       sqp = kzalloc(sizeof (struct mlx4_ib_sqp), gfp);
+                       sqp = kzalloc(sizeof(struct mlx4_ib_sqp), GFP_KERNEL);
                        if (!sqp)
                                return -ENOMEM;
                        qp = &sqp->qp;
                        qp->pri.vid = 0xFFFF;
                        qp->alt.vid = 0xFFFF;
                } else {
-                       qp = kzalloc(sizeof (struct mlx4_ib_qp), gfp);
+                       qp = kzalloc(sizeof(struct mlx4_ib_qp), GFP_KERNEL);
                        if (!qp)
                                return -ENOMEM;
                        qp->pri.vid = 0xFFFF;
@@ -780,7 +780,7 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
                        goto err;
 
                if (qp_has_rq(init_attr)) {
-                       err = mlx4_db_alloc(dev->dev, &qp->db, 0, gfp);
+                       err = mlx4_db_alloc(dev->dev, &qp->db, 0);
                        if (err)
                                goto err;
 
@@ -788,7 +788,7 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
                }
 
                if (mlx4_buf_alloc(dev->dev, qp->buf_size, qp->buf_size,
-                                  &qp->buf, gfp)) {
+                                  &qp->buf)) {
                        memcpy(&init_attr->cap, &backup_cap,
                               sizeof(backup_cap));
                        err = set_kernel_sq_size(dev, &init_attr->cap, qp_type,
@@ -797,7 +797,7 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
                                goto err_db;
 
                        if (mlx4_buf_alloc(dev->dev, qp->buf_size,
-                                          PAGE_SIZE * 2, &qp->buf, gfp)) {
+                                          PAGE_SIZE * 2, &qp->buf)) {
                                err = -ENOMEM;
                                goto err_db;
                        }
@@ -808,20 +808,20 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
                if (err)
                        goto err_buf;
 
-               err = mlx4_buf_write_mtt(dev->dev, &qp->mtt, &qp->buf, gfp);
+               err = mlx4_buf_write_mtt(dev->dev, &qp->mtt, &qp->buf);
                if (err)
                        goto err_mtt;
 
                qp->sq.wrid = kmalloc_array(qp->sq.wqe_cnt, sizeof(u64),
-                                       gfp | __GFP_NOWARN);
+                                       GFP_KERNEL | __GFP_NOWARN);
                if (!qp->sq.wrid)
                        qp->sq.wrid = __vmalloc(qp->sq.wqe_cnt * sizeof(u64),
-                                               gfp, PAGE_KERNEL);
+                                               GFP_KERNEL, PAGE_KERNEL);
                qp->rq.wrid = kmalloc_array(qp->rq.wqe_cnt, sizeof(u64),
-                                       gfp | __GFP_NOWARN);
+                                       GFP_KERNEL | __GFP_NOWARN);
                if (!qp->rq.wrid)
                        qp->rq.wrid = __vmalloc(qp->rq.wqe_cnt * sizeof(u64),
-                                               gfp, PAGE_KERNEL);
+                                               GFP_KERNEL, PAGE_KERNEL);
                if (!qp->sq.wrid || !qp->rq.wrid) {
                        err = -ENOMEM;
                        goto err_wrid;
@@ -859,7 +859,7 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
        if (init_attr->create_flags & IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK)
                qp->flags |= MLX4_IB_QP_BLOCK_MULTICAST_LOOPBACK;
 
-       err = mlx4_qp_alloc(dev->dev, qpn, &qp->mqp, gfp);
+       err = mlx4_qp_alloc(dev->dev, qpn, &qp->mqp);
        if (err)
                goto err_qpn;
 
@@ -1127,10 +1127,7 @@ static struct ib_qp *_mlx4_ib_create_qp(struct ib_pd *pd,
        int err;
        int sup_u_create_flags = MLX4_IB_QP_BLOCK_MULTICAST_LOOPBACK;
        u16 xrcdn = 0;
-       gfp_t gfp;
 
-       gfp = (init_attr->create_flags & MLX4_IB_QP_CREATE_USE_GFP_NOIO) ?
-               GFP_NOIO : GFP_KERNEL;
        /*
         * We only support LSO, vendor flag1, and multicast loopback blocking,
         * and only for kernel UD QPs.
@@ -1140,8 +1137,7 @@ static struct ib_qp *_mlx4_ib_create_qp(struct ib_pd *pd,
                                        MLX4_IB_SRIOV_TUNNEL_QP |
                                        MLX4_IB_SRIOV_SQP |
                                        MLX4_IB_QP_NETIF |
-                                       MLX4_IB_QP_CREATE_ROCE_V2_GSI |
-                                       MLX4_IB_QP_CREATE_USE_GFP_NOIO))
+                                       MLX4_IB_QP_CREATE_ROCE_V2_GSI))
                return ERR_PTR(-EINVAL);
 
        if (init_attr->create_flags & IB_QP_CREATE_NETIF_QP) {
@@ -1154,7 +1150,6 @@ static struct ib_qp *_mlx4_ib_create_qp(struct ib_pd *pd,
                        return ERR_PTR(-EINVAL);
 
                if ((init_attr->create_flags & ~(MLX4_IB_SRIOV_SQP |
-                                                MLX4_IB_QP_CREATE_USE_GFP_NOIO |
                                                 MLX4_IB_QP_CREATE_ROCE_V2_GSI  |
                                                 MLX4_IB_QP_BLOCK_MULTICAST_LOOPBACK) &&
                     init_attr->qp_type != IB_QPT_UD) ||
@@ -1179,7 +1174,7 @@ static struct ib_qp *_mlx4_ib_create_qp(struct ib_pd *pd,
        case IB_QPT_RC:
        case IB_QPT_UC:
        case IB_QPT_RAW_PACKET:
-               qp = kzalloc(sizeof *qp, gfp);
+               qp = kzalloc(sizeof(*qp), GFP_KERNEL);
                if (!qp)
                        return ERR_PTR(-ENOMEM);
                qp->pri.vid = 0xFFFF;
@@ -1188,7 +1183,7 @@ static struct ib_qp *_mlx4_ib_create_qp(struct ib_pd *pd,
        case IB_QPT_UD:
        {
                err = create_qp_common(to_mdev(pd->device), pd, init_attr,
-                                      udata, 0, &qp, gfp);
+                                      udata, 0, &qp);
                if (err) {
                        kfree(qp);
                        return ERR_PTR(err);
@@ -1217,8 +1212,7 @@ static struct ib_qp *_mlx4_ib_create_qp(struct ib_pd *pd,
                }
 
                err = create_qp_common(to_mdev(pd->device), pd, init_attr, udata,
-                                      sqpn,
-                                      &qp, gfp);
+                                      sqpn, &qp);
                if (err)
                        return ERR_PTR(err);
 
index e32dd58937a821a914c3e7d79d2d4482b158db47..0facaf5f6d2376d395a739726b740b1d6f352435 100644 (file)
@@ -135,14 +135,14 @@ struct ib_srq *mlx4_ib_create_srq(struct ib_pd *pd,
                if (err)
                        goto err_mtt;
        } else {
-               err = mlx4_db_alloc(dev->dev, &srq->db, 0, GFP_KERNEL);
+               err = mlx4_db_alloc(dev->dev, &srq->db, 0);
                if (err)
                        goto err_srq;
 
                *srq->db.db = 0;
 
-               if (mlx4_buf_alloc(dev->dev, buf_size, PAGE_SIZE * 2, &srq->buf,
-                                  GFP_KERNEL)) {
+               if (mlx4_buf_alloc(dev->dev, buf_size, PAGE_SIZE * 2,
+                                  &srq->buf)) {
                        err = -ENOMEM;
                        goto err_db;
                }
@@ -167,7 +167,7 @@ struct ib_srq *mlx4_ib_create_srq(struct ib_pd *pd,
                if (err)
                        goto err_buf;
 
-               err = mlx4_buf_write_mtt(dev->dev, &srq->mtt, &srq->buf, GFP_KERNEL);
+               err = mlx4_buf_write_mtt(dev->dev, &srq->mtt, &srq->buf);
                if (err)
                        goto err_mtt;
 
index 763bb5b36144be84c9ba2eafa7b3ade06fa57f44..8ab2f1360a4564f6477420b6ab1b03811d360f19 100644 (file)
@@ -582,6 +582,15 @@ static void clean_keys(struct mlx5_ib_dev *dev, int c)
        }
 }
 
+static void mlx5_mr_cache_debugfs_cleanup(struct mlx5_ib_dev *dev)
+{
+       if (!mlx5_debugfs_root)
+               return;
+
+       debugfs_remove_recursive(dev->cache.root);
+       dev->cache.root = NULL;
+}
+
 static int mlx5_mr_cache_debugfs_init(struct mlx5_ib_dev *dev)
 {
        struct mlx5_mr_cache *cache = &dev->cache;
@@ -600,38 +609,34 @@ static int mlx5_mr_cache_debugfs_init(struct mlx5_ib_dev *dev)
                sprintf(ent->name, "%d", ent->order);
                ent->dir = debugfs_create_dir(ent->name,  cache->root);
                if (!ent->dir)
-                       return -ENOMEM;
+                       goto err;
 
                ent->fsize = debugfs_create_file("size", 0600, ent->dir, ent,
                                                 &size_fops);
                if (!ent->fsize)
-                       return -ENOMEM;
+                       goto err;
 
                ent->flimit = debugfs_create_file("limit", 0600, ent->dir, ent,
                                                  &limit_fops);
                if (!ent->flimit)
-                       return -ENOMEM;
+                       goto err;
 
                ent->fcur = debugfs_create_u32("cur", 0400, ent->dir,
                                               &ent->cur);
                if (!ent->fcur)
-                       return -ENOMEM;
+                       goto err;
 
                ent->fmiss = debugfs_create_u32("miss", 0600, ent->dir,
                                                &ent->miss);
                if (!ent->fmiss)
-                       return -ENOMEM;
+                       goto err;
        }
 
        return 0;
-}
-
-static void mlx5_mr_cache_debugfs_cleanup(struct mlx5_ib_dev *dev)
-{
-       if (!mlx5_debugfs_root)
-               return;
+err:
+       mlx5_mr_cache_debugfs_cleanup(dev);
 
-       debugfs_remove_recursive(dev->cache.root);
+       return -ENOMEM;
 }
 
 static void delay_time_func(unsigned long ctx)
@@ -692,6 +697,11 @@ int mlx5_mr_cache_init(struct mlx5_ib_dev *dev)
        if (err)
                mlx5_ib_warn(dev, "cache debugfs failure\n");
 
+       /*
+        * We don't want to fail driver if debugfs failed to initialize,
+        * so we are not forwarding error to the user.
+        */
+
        return 0;
 }
 
@@ -1779,7 +1789,7 @@ mlx5_ib_sg_to_klms(struct mlx5_ib_mr *mr,
        mr->ndescs = sg_nents;
 
        for_each_sg(sgl, sg, sg_nents, i) {
-               if (unlikely(i > mr->max_descs))
+               if (unlikely(i >= mr->max_descs))
                        break;
                klms[i].va = cpu_to_be64(sg_dma_address(sg) + sg_offset);
                klms[i].bcount = cpu_to_be32(sg_dma_len(sg) - sg_offset);
index 8f9d8b4ad583918dc4a2785b1df33d6eee3b6921..b0adf65e4bdbf4c1e19f4b75c1b805b9d42ef622 100644 (file)
@@ -551,7 +551,7 @@ struct nes_adapter *nes_init_adapter(struct nes_device *nesdev, u8 hw_rev) {
                        if ((0x0F000100 == (pcs_control_status0 & 0x0F000100))
                            || (0x0F000100 == (pcs_control_status1 & 0x0F000100)))
                                int_cnt++;
-                       msleep(1);
+                       usleep_range(1000, 2000);
                }
                if (int_cnt > 1) {
                        spin_lock_irqsave(&nesadapter->phy_lock, flags);
@@ -592,7 +592,7 @@ struct nes_adapter *nes_init_adapter(struct nes_device *nesdev, u8 hw_rev) {
                                                break;
                                        }
                                }
-                               msleep(1);
+                               usleep_range(1000, 2000);
                        }
                }
        }
index 5984981e7dd41b9c681e44bd275e230d19f29bd5..a343e3b5d4cbf1188db5801b0856b13ad08ff72e 100644 (file)
@@ -104,10 +104,9 @@ const struct rvt_operation_params qib_post_parms[RVT_OPERATION_MAX] = {
 
 };
 
-static void get_map_page(struct rvt_qpn_table *qpt, struct rvt_qpn_map *map,
-                        gfp_t gfp)
+static void get_map_page(struct rvt_qpn_table *qpt, struct rvt_qpn_map *map)
 {
-       unsigned long page = get_zeroed_page(gfp);
+       unsigned long page = get_zeroed_page(GFP_KERNEL);
 
        /*
         * Free the page if someone raced with us installing it.
@@ -126,7 +125,7 @@ static void get_map_page(struct rvt_qpn_table *qpt, struct rvt_qpn_map *map,
  * zero/one for QP type IB_QPT_SMI/IB_QPT_GSI.
  */
 int qib_alloc_qpn(struct rvt_dev_info *rdi, struct rvt_qpn_table *qpt,
-                 enum ib_qp_type type, u8 port, gfp_t gfp)
+                 enum ib_qp_type type, u8 port)
 {
        u32 i, offset, max_scan, qpn;
        struct rvt_qpn_map *map;
@@ -160,7 +159,7 @@ int qib_alloc_qpn(struct rvt_dev_info *rdi, struct rvt_qpn_table *qpt,
        max_scan = qpt->nmaps - !offset;
        for (i = 0;;) {
                if (unlikely(!map->page)) {
-                       get_map_page(qpt, map, gfp);
+                       get_map_page(qpt, map);
                        if (unlikely(!map->page))
                                break;
                }
@@ -317,16 +316,16 @@ u32 qib_mtu_from_qp(struct rvt_dev_info *rdi, struct rvt_qp *qp, u32 pmtu)
        return ib_mtu_enum_to_int(pmtu);
 }
 
-void *qib_qp_priv_alloc(struct rvt_dev_info *rdi, struct rvt_qp *qp, gfp_t gfp)
+void *qib_qp_priv_alloc(struct rvt_dev_info *rdi, struct rvt_qp *qp)
 {
        struct qib_qp_priv *priv;
 
-       priv = kzalloc(sizeof(*priv), gfp);
+       priv = kzalloc(sizeof(*priv), GFP_KERNEL);
        if (!priv)
                return ERR_PTR(-ENOMEM);
        priv->owner = qp;
 
-       priv->s_hdr = kzalloc(sizeof(*priv->s_hdr), gfp);
+       priv->s_hdr = kzalloc(sizeof(*priv->s_hdr), GFP_KERNEL);
        if (!priv->s_hdr) {
                kfree(priv);
                return ERR_PTR(-ENOMEM);
index da0db5485ddc7129151c10e8ec66cf7aa6332594..a52fc67b40d73ab3e7e3c6659bf050cd16a0035d 100644 (file)
@@ -274,11 +274,11 @@ int qib_get_counters(struct qib_pportdata *ppd,
  * Functions provided by qib driver for rdmavt to use
  */
 unsigned qib_free_all_qps(struct rvt_dev_info *rdi);
-void *qib_qp_priv_alloc(struct rvt_dev_info *rdi, struct rvt_qp *qp, gfp_t gfp);
+void *qib_qp_priv_alloc(struct rvt_dev_info *rdi, struct rvt_qp *qp);
 void qib_qp_priv_free(struct rvt_dev_info *rdi, struct rvt_qp *qp);
 void qib_notify_qp_reset(struct rvt_qp *qp);
 int qib_alloc_qpn(struct rvt_dev_info *rdi, struct rvt_qpn_table *qpt,
-                 enum ib_qp_type type, u8 port, gfp_t gfp);
+                 enum ib_qp_type type, u8 port);
 void qib_restart_rc(struct rvt_qp *qp, u32 psn, int wait);
 #ifdef CONFIG_DEBUG_FS
 
index 727e81cc2c8f6ad71b66b486c9b3d581e66e47d0..459865439a0bf50affcd8300237e135fb03e9faa 100644 (file)
@@ -118,10 +118,9 @@ const int ib_rvt_state_ops[IB_QPS_ERR + 1] = {
 EXPORT_SYMBOL(ib_rvt_state_ops);
 
 static void get_map_page(struct rvt_qpn_table *qpt,
-                        struct rvt_qpn_map *map,
-                        gfp_t gfp)
+                        struct rvt_qpn_map *map)
 {
-       unsigned long page = get_zeroed_page(gfp);
+       unsigned long page = get_zeroed_page(GFP_KERNEL);
 
        /*
         * Free the page if someone raced with us installing it.
@@ -173,7 +172,7 @@ static int init_qpn_table(struct rvt_dev_info *rdi, struct rvt_qpn_table *qpt)
                    rdi->dparms.qpn_res_start, rdi->dparms.qpn_res_end);
        for (i = rdi->dparms.qpn_res_start; i <= rdi->dparms.qpn_res_end; i++) {
                if (!map->page) {
-                       get_map_page(qpt, map, GFP_KERNEL);
+                       get_map_page(qpt, map);
                        if (!map->page) {
                                ret = -ENOMEM;
                                break;
@@ -342,14 +341,14 @@ static inline unsigned mk_qpn(struct rvt_qpn_table *qpt,
  * Return: The queue pair number
  */
 static int alloc_qpn(struct rvt_dev_info *rdi, struct rvt_qpn_table *qpt,
-                    enum ib_qp_type type, u8 port_num, gfp_t gfp)
+                    enum ib_qp_type type, u8 port_num)
 {
        u32 i, offset, max_scan, qpn;
        struct rvt_qpn_map *map;
        u32 ret;
 
        if (rdi->driver_f.alloc_qpn)
-               return rdi->driver_f.alloc_qpn(rdi, qpt, type, port_num, gfp);
+               return rdi->driver_f.alloc_qpn(rdi, qpt, type, port_num);
 
        if (type == IB_QPT_SMI || type == IB_QPT_GSI) {
                unsigned n;
@@ -374,7 +373,7 @@ static int alloc_qpn(struct rvt_dev_info *rdi, struct rvt_qpn_table *qpt,
        max_scan = qpt->nmaps - !offset;
        for (i = 0;;) {
                if (unlikely(!map->page)) {
-                       get_map_page(qpt, map, gfp);
+                       get_map_page(qpt, map);
                        if (unlikely(!map->page))
                                break;
                }
@@ -672,7 +671,6 @@ struct ib_qp *rvt_create_qp(struct ib_pd *ibpd,
        struct ib_qp *ret = ERR_PTR(-ENOMEM);
        struct rvt_dev_info *rdi = ib_to_rvt(ibpd->device);
        void *priv = NULL;
-       gfp_t gfp;
        size_t sqsize;
 
        if (!rdi)
@@ -680,18 +678,9 @@ struct ib_qp *rvt_create_qp(struct ib_pd *ibpd,
 
        if (init_attr->cap.max_send_sge > rdi->dparms.props.max_sge ||
            init_attr->cap.max_send_wr > rdi->dparms.props.max_qp_wr ||
-           init_attr->create_flags & ~(IB_QP_CREATE_USE_GFP_NOIO))
+           init_attr->create_flags)
                return ERR_PTR(-EINVAL);
 
-       /* GFP_NOIO is applicable to RC QP's only */
-
-       if (init_attr->create_flags & IB_QP_CREATE_USE_GFP_NOIO &&
-           init_attr->qp_type != IB_QPT_RC)
-               return ERR_PTR(-EINVAL);
-
-       gfp = init_attr->create_flags & IB_QP_CREATE_USE_GFP_NOIO ?
-                                               GFP_NOIO : GFP_KERNEL;
-
        /* Check receive queue parameters if no SRQ is specified. */
        if (!init_attr->srq) {
                if (init_attr->cap.max_recv_sge > rdi->dparms.props.max_sge ||
@@ -719,14 +708,7 @@ struct ib_qp *rvt_create_qp(struct ib_pd *ibpd,
                sz = sizeof(struct rvt_sge) *
                        init_attr->cap.max_send_sge +
                        sizeof(struct rvt_swqe);
-               if (gfp == GFP_NOIO)
-                       swq = __vmalloc(
-                               sqsize * sz,
-                               gfp | __GFP_ZERO, PAGE_KERNEL);
-               else
-                       swq = vzalloc_node(
-                               sqsize * sz,
-                               rdi->dparms.node);
+               swq = vzalloc_node(sqsize * sz, rdi->dparms.node);
                if (!swq)
                        return ERR_PTR(-ENOMEM);
 
@@ -741,7 +723,8 @@ struct ib_qp *rvt_create_qp(struct ib_pd *ibpd,
                } else if (init_attr->cap.max_recv_sge > 1)
                        sg_list_sz = sizeof(*qp->r_sg_list) *
                                (init_attr->cap.max_recv_sge - 1);
-               qp = kzalloc_node(sz + sg_list_sz, gfp, rdi->dparms.node);
+               qp = kzalloc_node(sz + sg_list_sz, GFP_KERNEL,
+                                 rdi->dparms.node);
                if (!qp)
                        goto bail_swq;
 
@@ -751,7 +734,7 @@ struct ib_qp *rvt_create_qp(struct ib_pd *ibpd,
                                kzalloc_node(
                                        sizeof(*qp->s_ack_queue) *
                                         rvt_max_atomic(rdi),
-                                       gfp,
+                                       GFP_KERNEL,
                                        rdi->dparms.node);
                        if (!qp->s_ack_queue)
                                goto bail_qp;
@@ -766,7 +749,7 @@ struct ib_qp *rvt_create_qp(struct ib_pd *ibpd,
                 * Driver needs to set up it's private QP structure and do any
                 * initialization that is needed.
                 */
-               priv = rdi->driver_f.qp_priv_alloc(rdi, qp, gfp);
+               priv = rdi->driver_f.qp_priv_alloc(rdi, qp);
                if (IS_ERR(priv)) {
                        ret = priv;
                        goto bail_qp;
@@ -786,11 +769,6 @@ struct ib_qp *rvt_create_qp(struct ib_pd *ibpd,
                                qp->r_rq.wq = vmalloc_user(
                                                sizeof(struct rvt_rwq) +
                                                qp->r_rq.size * sz);
-                       else if (gfp == GFP_NOIO)
-                               qp->r_rq.wq = __vmalloc(
-                                               sizeof(struct rvt_rwq) +
-                                               qp->r_rq.size * sz,
-                                               gfp | __GFP_ZERO, PAGE_KERNEL);
                        else
                                qp->r_rq.wq = vzalloc_node(
                                                sizeof(struct rvt_rwq) +
@@ -824,7 +802,7 @@ struct ib_qp *rvt_create_qp(struct ib_pd *ibpd,
 
                err = alloc_qpn(rdi, &rdi->qp_dev->qpn_table,
                                init_attr->qp_type,
-                               init_attr->port_num, gfp);
+                               init_attr->port_num);
                if (err < 0) {
                        ret = ERR_PTR(err);
                        goto bail_rq_wq;
index c3a140ed4df27a0abf33ce0a032774d250883faa..08f3f90d29123e9f6840b34f72b8aa56b7054b7d 100644 (file)
@@ -441,6 +441,8 @@ static void rxe_skb_tx_dtor(struct sk_buff *skb)
        if (unlikely(qp->need_req_skb &&
                     skb_out < RXE_INFLIGHT_SKBS_PER_QP_LOW))
                rxe_run_task(&qp->req.task, 1);
+
+       rxe_drop_ref(qp);
 }
 
 int rxe_send(struct rxe_dev *rxe, struct rxe_pkt_info *pkt, struct sk_buff *skb)
@@ -473,6 +475,7 @@ int rxe_send(struct rxe_dev *rxe, struct rxe_pkt_info *pkt, struct sk_buff *skb)
                return -EAGAIN;
        }
 
+       rxe_add_ref(pkt->qp);
        atomic_inc(&pkt->qp->skb_out);
        kfree_skb(skb);
 
index 073e66783f1dd8a4b62f9fc59a84319b507b51b8..07511718d98d8cd88da3b5dff46affbc21671c0e 100644 (file)
@@ -1240,6 +1240,8 @@ int rxe_register_device(struct rxe_dev *rxe)
        addrconf_addr_eui48((unsigned char *)&dev->node_guid,
                            rxe->ndev->dev_addr);
        dev->dev.dma_ops = &dma_virt_ops;
+       dma_coerce_mask_and_coherent(&dev->dev,
+                                    dma_get_required_mask(dev->dev.parent));
 
        dev->uverbs_abi_ver = RXE_UVERBS_ABI_VERSION;
        dev->uverbs_cmd_mask = BIT_ULL(IB_USER_VERBS_CMD_GET_CONTEXT)
index 7cbcfdac6529cc5a93f43212a3d05744985f814c..f87d104837dcfab7f0e35b5b7fcae1e021599bfc 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/vmalloc.h>
 #include <linux/moduleparam.h>
 #include <linux/sched/signal.h>
+#include <linux/sched/mm.h>
 
 #include "ipoib.h"
 
@@ -954,7 +955,7 @@ void ipoib_cm_dev_stop(struct net_device *dev)
                        break;
                }
                spin_unlock_irq(&priv->lock);
-               msleep(1);
+               usleep_range(1000, 2000);
                ipoib_drain_cq(dev);
                spin_lock_irq(&priv->lock);
        }
@@ -1047,9 +1048,8 @@ static struct ib_qp *ipoib_cm_create_tx_qp(struct net_device *dev, struct ipoib_
                .sq_sig_type            = IB_SIGNAL_ALL_WR,
                .qp_type                = IB_QPT_RC,
                .qp_context             = tx,
-               .create_flags           = IB_QP_CREATE_USE_GFP_NOIO
+               .create_flags           = 0
        };
-
        struct ib_qp *tx_qp;
 
        if (dev->features & NETIF_F_SG)
@@ -1057,10 +1057,6 @@ static struct ib_qp *ipoib_cm_create_tx_qp(struct net_device *dev, struct ipoib_
                        min_t(u32, priv->ca->attrs.max_sge, MAX_SKB_FRAGS + 1);
 
        tx_qp = ib_create_qp(priv->pd, &attr);
-       if (PTR_ERR(tx_qp) == -EINVAL) {
-               attr.create_flags &= ~IB_QP_CREATE_USE_GFP_NOIO;
-               tx_qp = ib_create_qp(priv->pd, &attr);
-       }
        tx->max_send_sge = attr.cap.max_send_sge;
        return tx_qp;
 }
@@ -1131,10 +1127,11 @@ static int ipoib_cm_tx_init(struct ipoib_cm_tx *p, u32 qpn,
                            struct sa_path_rec *pathrec)
 {
        struct ipoib_dev_priv *priv = ipoib_priv(p->dev);
+       unsigned int noio_flag;
        int ret;
 
-       p->tx_ring = __vmalloc(ipoib_sendq_size * sizeof *p->tx_ring,
-                              GFP_NOIO, PAGE_KERNEL);
+       noio_flag = memalloc_noio_save();
+       p->tx_ring = vzalloc(ipoib_sendq_size * sizeof(*p->tx_ring));
        if (!p->tx_ring) {
                ret = -ENOMEM;
                goto err_tx;
@@ -1142,9 +1139,10 @@ static int ipoib_cm_tx_init(struct ipoib_cm_tx *p, u32 qpn,
        memset(p->tx_ring, 0, ipoib_sendq_size * sizeof *p->tx_ring);
 
        p->qp = ipoib_cm_create_tx_qp(p->dev, p);
+       memalloc_noio_restore(noio_flag);
        if (IS_ERR(p->qp)) {
                ret = PTR_ERR(p->qp);
-               ipoib_warn(priv, "failed to allocate tx qp: %d\n", ret);
+               ipoib_warn(priv, "failed to create tx qp: %d\n", ret);
                goto err_qp;
        }
 
@@ -1206,7 +1204,7 @@ static void ipoib_cm_tx_destroy(struct ipoib_cm_tx *p)
                                goto timeout;
                        }
 
-                       msleep(1);
+                       usleep_range(1000, 2000);
                }
        }
 
index efe7402f48852195efae4fc70cf843d0398dda30..57a9655e844deb1cc2eb57d9485f98e195368ac5 100644 (file)
@@ -770,7 +770,7 @@ int ipoib_ib_dev_stop_default(struct net_device *dev)
 
                ipoib_drain_cq(dev);
 
-               msleep(1);
+               usleep_range(1000, 2000);
        }
 
        ipoib_dbg(priv, "All sends and receives done.\n");
index 6e86eeee370e86602977bbf3f3949bf2d5ac26ef..70dacaf9044ecdd7b6c0be0ba20cd913cb66a4d4 100644 (file)
@@ -233,6 +233,7 @@ static netdev_features_t ipoib_fix_features(struct net_device *dev, netdev_featu
 static int ipoib_change_mtu(struct net_device *dev, int new_mtu)
 {
        struct ipoib_dev_priv *priv = ipoib_priv(dev);
+       int ret = 0;
 
        /* dev->mtu > 2K ==> connected mode */
        if (ipoib_cm_admin_enabled(dev)) {
@@ -256,9 +257,34 @@ static int ipoib_change_mtu(struct net_device *dev, int new_mtu)
                ipoib_dbg(priv, "MTU must be smaller than the underlying "
                                "link layer MTU - 4 (%u)\n", priv->mcast_mtu);
 
-       dev->mtu = min(priv->mcast_mtu, priv->admin_mtu);
+       new_mtu = min(priv->mcast_mtu, priv->admin_mtu);
 
-       return 0;
+       if (priv->rn_ops->ndo_change_mtu) {
+               bool carrier_status = netif_carrier_ok(dev);
+
+               netif_carrier_off(dev);
+
+               /* notify lower level on the real mtu */
+               ret = priv->rn_ops->ndo_change_mtu(dev, new_mtu);
+
+               if (carrier_status)
+                       netif_carrier_on(dev);
+       } else {
+               dev->mtu = new_mtu;
+       }
+
+       return ret;
+}
+
+static void ipoib_get_stats(struct net_device *dev,
+                           struct rtnl_link_stats64 *stats)
+{
+       struct ipoib_dev_priv *priv = ipoib_priv(dev);
+
+       if (priv->rn_ops->ndo_get_stats64)
+               priv->rn_ops->ndo_get_stats64(dev, stats);
+       else
+               netdev_stats_to_stats64(stats, &dev->stats);
 }
 
 /* Called with an RCU read lock taken */
@@ -1808,6 +1834,7 @@ static const struct net_device_ops ipoib_netdev_ops_pf = {
        .ndo_get_vf_stats        = ipoib_get_vf_stats,
        .ndo_set_vf_guid         = ipoib_set_vf_guid,
        .ndo_set_mac_address     = ipoib_set_mac,
+       .ndo_get_stats64         = ipoib_get_stats,
 };
 
 static const struct net_device_ops ipoib_netdev_ops_vf = {
index 5a887efb4bdf1b6405d3fc4342918084ae420b57..37b33d708c2dd5aecfa9bcc0328fb60876e9c310 100644 (file)
@@ -83,6 +83,7 @@ static struct scsi_host_template iscsi_iser_sht;
 static struct iscsi_transport iscsi_iser_transport;
 static struct scsi_transport_template *iscsi_iser_scsi_transport;
 static struct workqueue_struct *release_wq;
+static DEFINE_MUTEX(unbind_iser_conn_mutex);
 struct iser_global ig;
 
 int iser_debug_level = 0;
@@ -550,12 +551,14 @@ iscsi_iser_conn_stop(struct iscsi_cls_conn *cls_conn, int flag)
         */
        if (iser_conn) {
                mutex_lock(&iser_conn->state_mutex);
+               mutex_lock(&unbind_iser_conn_mutex);
                iser_conn_terminate(iser_conn);
                iscsi_conn_stop(cls_conn, flag);
 
                /* unbind */
                iser_conn->iscsi_conn = NULL;
                conn->dd_data = NULL;
+               mutex_unlock(&unbind_iser_conn_mutex);
 
                complete(&iser_conn->stop_completion);
                mutex_unlock(&iser_conn->state_mutex);
@@ -977,13 +980,21 @@ static int iscsi_iser_slave_alloc(struct scsi_device *sdev)
        struct iser_conn *iser_conn;
        struct ib_device *ib_dev;
 
+       mutex_lock(&unbind_iser_conn_mutex);
+
        session = starget_to_session(scsi_target(sdev))->dd_data;
        iser_conn = session->leadconn->dd_data;
+       if (!iser_conn) {
+               mutex_unlock(&unbind_iser_conn_mutex);
+               return -ENOTCONN;
+       }
        ib_dev = iser_conn->ib_conn.device->ib_device;
 
        if (!(ib_dev->attrs.device_cap_flags & IB_DEVICE_SG_GAPS_REG))
                blk_queue_virt_boundary(sdev->request_queue, ~MASK_4K);
 
+       mutex_unlock(&unbind_iser_conn_mutex);
+
        return 0;
 }
 
index c538a38c91ce95acf8e00fcdf43fa28588ad2f49..26a004e97ae0fc3d4f7d257e725313f4b75ed82e 100644 (file)
@@ -708,8 +708,14 @@ iser_calc_scsi_params(struct iser_conn *iser_conn,
        unsigned short sg_tablesize, sup_sg_tablesize;
 
        sg_tablesize = DIV_ROUND_UP(max_sectors * 512, SIZE_4K);
-       sup_sg_tablesize = min_t(unsigned, ISCSI_ISER_MAX_SG_TABLESIZE,
-                                device->ib_device->attrs.max_fast_reg_page_list_len);
+       if (device->ib_device->attrs.device_cap_flags &
+                       IB_DEVICE_MEM_MGT_EXTENSIONS)
+               sup_sg_tablesize =
+                       min_t(
+                        uint, ISCSI_ISER_MAX_SG_TABLESIZE,
+                        device->ib_device->attrs.max_fast_reg_page_list_len);
+       else
+               sup_sg_tablesize = ISCSI_ISER_MAX_SG_TABLESIZE;
 
        iser_conn->scsi_sg_tablesize = min(sg_tablesize, sup_sg_tablesize);
 }
index f4eace5ea184095eb0c170c4f3f1647f72b8c537..40f3cd7eab0fc69ef0ea3e79efa079a33fc78aaf 100644 (file)
@@ -156,7 +156,8 @@ static int read_sb_page(struct mddev *mddev, loff_t offset,
 
        rdev_for_each(rdev, mddev) {
                if (! test_bit(In_sync, &rdev->flags)
-                   || test_bit(Faulty, &rdev->flags))
+                   || test_bit(Faulty, &rdev->flags)
+                   || test_bit(Bitmap_sync, &rdev->flags))
                        continue;
 
                target = offset + index * (PAGE_SIZE/512);
index 991f0fe2dcc684a7f0cb2c5c51902b3dc9a19af8..b50eb4ac1b8291444e1af5196b44f5c7da368842 100644 (file)
@@ -134,7 +134,9 @@ enum flag_bits {
        Faulty,                 /* device is known to have a fault */
        In_sync,                /* device is in_sync with rest of array */
        Bitmap_sync,            /* ..actually, not quite In_sync.  Need a
-                                * bitmap-based recovery to get fully in sync
+                                * bitmap-based recovery to get fully in sync.
+                                * The bit is only meaningful before device
+                                * has been passed to pers->hot_add_disk.
                                 */
        WriteMostly,            /* Avoid reading if at all possible */
        AutoDetected,           /* added by auto-detect */
index 77cce3573aa85b40b6e2492ac458405426cdaf6e..44ad5baf320684e61b1aee1549d15b6e68c0a732 100644 (file)
@@ -1150,7 +1150,7 @@ int ppl_init_log(struct r5conf *conf)
                goto err;
        }
 
-       ppl_conf->bs = bioset_create(conf->raid_disks, 0, 0);
+       ppl_conf->bs = bioset_create(conf->raid_disks, 0, BIOSET_NEED_BVECS);
        if (!ppl_conf->bs) {
                ret = -ENOMEM;
                goto err;
index 2ceb338b094b2bd41c2a788ed5c9efe448bf1568..aeeb8d6854e2610dd2e006aa419264415d950da7 100644 (file)
@@ -7951,12 +7951,10 @@ static void end_reshape(struct r5conf *conf)
 {
 
        if (!test_bit(MD_RECOVERY_INTR, &conf->mddev->recovery)) {
-               struct md_rdev *rdev;
 
                spin_lock_irq(&conf->device_lock);
                conf->previous_raid_disks = conf->raid_disks;
-               rdev_for_each(rdev, conf->mddev)
-                       rdev->data_offset = rdev->new_data_offset;
+               md_finish_reshape(conf->mddev);
                smp_wmb();
                conf->reshape_progress = MaxSector;
                conf->mddev->reshape_position = MaxSector;
index 249a4584401ad487629c03b92a52f728d3318307..d94b3744a5b915c5c972a9ac4ab649f0b00fe9ab 100644 (file)
@@ -578,7 +578,7 @@ out:
 }
 
 static int mlx4_buf_direct_alloc(struct mlx4_dev *dev, int size,
-                                struct mlx4_buf *buf, gfp_t gfp)
+                                struct mlx4_buf *buf)
 {
        dma_addr_t t;
 
@@ -587,7 +587,7 @@ static int mlx4_buf_direct_alloc(struct mlx4_dev *dev, int size,
        buf->page_shift   = get_order(size) + PAGE_SHIFT;
        buf->direct.buf   =
                dma_zalloc_coherent(&dev->persist->pdev->dev,
-                                   size, &t, gfp);
+                                   size, &t, GFP_KERNEL);
        if (!buf->direct.buf)
                return -ENOMEM;
 
@@ -607,10 +607,10 @@ static int mlx4_buf_direct_alloc(struct mlx4_dev *dev, int size,
  *  multiple pages, so we don't require too much contiguous memory.
  */
 int mlx4_buf_alloc(struct mlx4_dev *dev, int size, int max_direct,
-                  struct mlx4_buf *buf, gfp_t gfp)
+                  struct mlx4_buf *buf)
 {
        if (size <= max_direct) {
-               return mlx4_buf_direct_alloc(dev, size, buf, gfp);
+               return mlx4_buf_direct_alloc(dev, size, buf);
        } else {
                dma_addr_t t;
                int i;
@@ -620,14 +620,14 @@ int mlx4_buf_alloc(struct mlx4_dev *dev, int size, int max_direct,
                buf->npages     = buf->nbufs;
                buf->page_shift  = PAGE_SHIFT;
                buf->page_list   = kcalloc(buf->nbufs, sizeof(*buf->page_list),
-                                          gfp);
+                                          GFP_KERNEL);
                if (!buf->page_list)
                        return -ENOMEM;
 
                for (i = 0; i < buf->nbufs; ++i) {
                        buf->page_list[i].buf =
                                dma_zalloc_coherent(&dev->persist->pdev->dev,
-                                                   PAGE_SIZE, &t, gfp);
+                                                   PAGE_SIZE, &t, GFP_KERNEL);
                        if (!buf->page_list[i].buf)
                                goto err_free;
 
@@ -663,12 +663,11 @@ void mlx4_buf_free(struct mlx4_dev *dev, int size, struct mlx4_buf *buf)
 }
 EXPORT_SYMBOL_GPL(mlx4_buf_free);
 
-static struct mlx4_db_pgdir *mlx4_alloc_db_pgdir(struct device *dma_device,
-                                                gfp_t gfp)
+static struct mlx4_db_pgdir *mlx4_alloc_db_pgdir(struct device *dma_device)
 {
        struct mlx4_db_pgdir *pgdir;
 
-       pgdir = kzalloc(sizeof *pgdir, gfp);
+       pgdir = kzalloc(sizeof(*pgdir), GFP_KERNEL);
        if (!pgdir)
                return NULL;
 
@@ -676,7 +675,7 @@ static struct mlx4_db_pgdir *mlx4_alloc_db_pgdir(struct device *dma_device,
        pgdir->bits[0] = pgdir->order0;
        pgdir->bits[1] = pgdir->order1;
        pgdir->db_page = dma_alloc_coherent(dma_device, PAGE_SIZE,
-                                           &pgdir->db_dma, gfp);
+                                           &pgdir->db_dma, GFP_KERNEL);
        if (!pgdir->db_page) {
                kfree(pgdir);
                return NULL;
@@ -716,7 +715,7 @@ found:
        return 0;
 }
 
-int mlx4_db_alloc(struct mlx4_dev *dev, struct mlx4_db *db, int order, gfp_t gfp)
+int mlx4_db_alloc(struct mlx4_dev *dev, struct mlx4_db *db, int order)
 {
        struct mlx4_priv *priv = mlx4_priv(dev);
        struct mlx4_db_pgdir *pgdir;
@@ -728,7 +727,7 @@ int mlx4_db_alloc(struct mlx4_dev *dev, struct mlx4_db *db, int order, gfp_t gfp
                if (!mlx4_alloc_db_from_pgdir(pgdir, db, order))
                        goto out;
 
-       pgdir = mlx4_alloc_db_pgdir(&dev->persist->pdev->dev, gfp);
+       pgdir = mlx4_alloc_db_pgdir(&dev->persist->pdev->dev);
        if (!pgdir) {
                ret = -ENOMEM;
                goto out;
@@ -780,13 +779,13 @@ int mlx4_alloc_hwq_res(struct mlx4_dev *dev, struct mlx4_hwq_resources *wqres,
 {
        int err;
 
-       err = mlx4_db_alloc(dev, &wqres->db, 1, GFP_KERNEL);
+       err = mlx4_db_alloc(dev, &wqres->db, 1);
        if (err)
                return err;
 
        *wqres->db.db = 0;
 
-       err = mlx4_buf_direct_alloc(dev, size, &wqres->buf, GFP_KERNEL);
+       err = mlx4_buf_direct_alloc(dev, size, &wqres->buf);
        if (err)
                goto err_db;
 
@@ -795,7 +794,7 @@ int mlx4_alloc_hwq_res(struct mlx4_dev *dev, struct mlx4_hwq_resources *wqres,
        if (err)
                goto err_buf;
 
-       err = mlx4_buf_write_mtt(dev, &wqres->mtt, &wqres->buf, GFP_KERNEL);
+       err = mlx4_buf_write_mtt(dev, &wqres->mtt, &wqres->buf);
        if (err)
                goto err_mtt;
 
index fa6d2354a0e910ee160863e3cbe21a512d77bf03..c56a511b918e034e10fdb055c77785ea4a90b27a 100644 (file)
@@ -224,11 +224,11 @@ int __mlx4_cq_alloc_icm(struct mlx4_dev *dev, int *cqn)
        if (*cqn == -1)
                return -ENOMEM;
 
-       err = mlx4_table_get(dev, &cq_table->table, *cqn, GFP_KERNEL);
+       err = mlx4_table_get(dev, &cq_table->table, *cqn);
        if (err)
                goto err_out;
 
-       err = mlx4_table_get(dev, &cq_table->cmpt_table, *cqn, GFP_KERNEL);
+       err = mlx4_table_get(dev, &cq_table->cmpt_table, *cqn);
        if (err)
                goto err_put;
        return 0;
index e5fb89505a134dbbfc54ee8af136432e9dfcf573..436f7689a03212943d5ea70a2214774d2c940d97 100644 (file)
@@ -1042,7 +1042,7 @@ static int mlx4_en_config_rss_qp(struct mlx4_en_priv *priv, int qpn,
        if (!context)
                return -ENOMEM;
 
-       err = mlx4_qp_alloc(mdev->dev, qpn, qp, GFP_KERNEL);
+       err = mlx4_qp_alloc(mdev->dev, qpn, qp);
        if (err) {
                en_err(priv, "Failed to allocate qp #%x\n", qpn);
                goto out;
@@ -1086,7 +1086,7 @@ int mlx4_en_create_drop_qp(struct mlx4_en_priv *priv)
                en_err(priv, "Failed reserving drop qpn\n");
                return err;
        }
-       err = mlx4_qp_alloc(priv->mdev->dev, qpn, &priv->drop_qp, GFP_KERNEL);
+       err = mlx4_qp_alloc(priv->mdev->dev, qpn, &priv->drop_qp);
        if (err) {
                en_err(priv, "Failed allocating drop qp\n");
                mlx4_qp_release_range(priv->mdev->dev, qpn, 1);
@@ -1158,8 +1158,7 @@ int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv)
        }
 
        /* Configure RSS indirection qp */
-       err = mlx4_qp_alloc(mdev->dev, priv->base_qpn, rss_map->indir_qp,
-                           GFP_KERNEL);
+       err = mlx4_qp_alloc(mdev->dev, priv->base_qpn, rss_map->indir_qp);
        if (err) {
                en_err(priv, "Failed to allocate RSS indirection QP\n");
                goto rss_err;
index 4f3a9b27ce4ad647a8a932001f5b2e16e3525b92..73faa3d779214d86d3c653f9065518375039c7ce 100644 (file)
@@ -111,7 +111,7 @@ int mlx4_en_create_tx_ring(struct mlx4_en_priv *priv,
                goto err_hwq_res;
        }
 
-       err = mlx4_qp_alloc(mdev->dev, ring->qpn, &ring->sp_qp, GFP_KERNEL);
+       err = mlx4_qp_alloc(mdev->dev, ring->qpn, &ring->sp_qp);
        if (err) {
                en_err(priv, "Failed allocating qp %d\n", ring->qpn);
                goto err_reserve;
index e1f9e7cebf8f7adcf0a095513086b949c246aab6..5a7816e7c7b4e1ad129f176ae148d217cb5e86e6 100644 (file)
@@ -251,8 +251,7 @@ int mlx4_UNMAP_ICM_AUX(struct mlx4_dev *dev)
                        MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE);
 }
 
-int mlx4_table_get(struct mlx4_dev *dev, struct mlx4_icm_table *table, u32 obj,
-                  gfp_t gfp)
+int mlx4_table_get(struct mlx4_dev *dev, struct mlx4_icm_table *table, u32 obj)
 {
        u32 i = (obj & (table->num_obj - 1)) /
                        (MLX4_TABLE_CHUNK_SIZE / table->obj_size);
@@ -266,7 +265,7 @@ int mlx4_table_get(struct mlx4_dev *dev, struct mlx4_icm_table *table, u32 obj,
        }
 
        table->icm[i] = mlx4_alloc_icm(dev, MLX4_TABLE_CHUNK_SIZE >> PAGE_SHIFT,
-                                      (table->lowmem ? gfp : GFP_HIGHUSER) |
+                                      (table->lowmem ? GFP_KERNEL : GFP_HIGHUSER) |
                                       __GFP_NOWARN, table->coherent);
        if (!table->icm[i]) {
                ret = -ENOMEM;
@@ -363,7 +362,7 @@ int mlx4_table_get_range(struct mlx4_dev *dev, struct mlx4_icm_table *table,
        u32 i;
 
        for (i = start; i <= end; i += inc) {
-               err = mlx4_table_get(dev, table, i, GFP_KERNEL);
+               err = mlx4_table_get(dev, table, i);
                if (err)
                        goto fail;
        }
index 0c73645501509d752f8316da7c72fefe8deb03f9..dee67fa39107f890508e158e56b680af6496d74a 100644 (file)
@@ -71,8 +71,7 @@ struct mlx4_icm *mlx4_alloc_icm(struct mlx4_dev *dev, int npages,
                                gfp_t gfp_mask, int coherent);
 void mlx4_free_icm(struct mlx4_dev *dev, struct mlx4_icm *icm, int coherent);
 
-int mlx4_table_get(struct mlx4_dev *dev, struct mlx4_icm_table *table, u32 obj,
-                  gfp_t gfp);
+int mlx4_table_get(struct mlx4_dev *dev, struct mlx4_icm_table *table, u32 obj);
 void mlx4_table_put(struct mlx4_dev *dev, struct mlx4_icm_table *table, u32 obj);
 int mlx4_table_get_range(struct mlx4_dev *dev, struct mlx4_icm_table *table,
                         u32 start, u32 end);
index 30616cd0140d573573f5f334b937522a9a7c0974..706d7f21ac5c10b439ca3f9398c855488604a50d 100644 (file)
@@ -969,7 +969,7 @@ void mlx4_cleanup_cq_table(struct mlx4_dev *dev);
 void mlx4_cleanup_qp_table(struct mlx4_dev *dev);
 void mlx4_cleanup_srq_table(struct mlx4_dev *dev);
 void mlx4_cleanup_mcg_table(struct mlx4_dev *dev);
-int __mlx4_qp_alloc_icm(struct mlx4_dev *dev, int qpn, gfp_t gfp);
+int __mlx4_qp_alloc_icm(struct mlx4_dev *dev, int qpn);
 void __mlx4_qp_free_icm(struct mlx4_dev *dev, int qpn);
 int __mlx4_cq_alloc_icm(struct mlx4_dev *dev, int *cqn);
 void __mlx4_cq_free_icm(struct mlx4_dev *dev, int cqn);
@@ -977,7 +977,7 @@ int __mlx4_srq_alloc_icm(struct mlx4_dev *dev, int *srqn);
 void __mlx4_srq_free_icm(struct mlx4_dev *dev, int srqn);
 int __mlx4_mpt_reserve(struct mlx4_dev *dev);
 void __mlx4_mpt_release(struct mlx4_dev *dev, u32 index);
-int __mlx4_mpt_alloc_icm(struct mlx4_dev *dev, u32 index, gfp_t gfp);
+int __mlx4_mpt_alloc_icm(struct mlx4_dev *dev, u32 index);
 void __mlx4_mpt_free_icm(struct mlx4_dev *dev, u32 index);
 u32 __mlx4_alloc_mtt_range(struct mlx4_dev *dev, int order);
 void __mlx4_free_mtt_range(struct mlx4_dev *dev, u32 first_seg, int order);
index ce852ca22a968673b46d3f92d3a1ab3e526864fa..24282cd017d37e32d1653b1c3cb0bde1cc1af80a 100644 (file)
@@ -479,14 +479,14 @@ static void mlx4_mpt_release(struct mlx4_dev *dev, u32 index)
        __mlx4_mpt_release(dev, index);
 }
 
-int __mlx4_mpt_alloc_icm(struct mlx4_dev *dev, u32 index, gfp_t gfp)
+int __mlx4_mpt_alloc_icm(struct mlx4_dev *dev, u32 index)
 {
        struct mlx4_mr_table *mr_table = &mlx4_priv(dev)->mr_table;
 
-       return mlx4_table_get(dev, &mr_table->dmpt_table, index, gfp);
+       return mlx4_table_get(dev, &mr_table->dmpt_table, index);
 }
 
-static int mlx4_mpt_alloc_icm(struct mlx4_dev *dev, u32 index, gfp_t gfp)
+static int mlx4_mpt_alloc_icm(struct mlx4_dev *dev, u32 index)
 {
        u64 param = 0;
 
@@ -497,7 +497,7 @@ static int mlx4_mpt_alloc_icm(struct mlx4_dev *dev, u32 index, gfp_t gfp)
                                                        MLX4_CMD_TIME_CLASS_A,
                                                        MLX4_CMD_WRAPPED);
        }
-       return __mlx4_mpt_alloc_icm(dev, index, gfp);
+       return __mlx4_mpt_alloc_icm(dev, index);
 }
 
 void __mlx4_mpt_free_icm(struct mlx4_dev *dev, u32 index)
@@ -629,7 +629,7 @@ int mlx4_mr_enable(struct mlx4_dev *dev, struct mlx4_mr *mr)
        struct mlx4_mpt_entry *mpt_entry;
        int err;
 
-       err = mlx4_mpt_alloc_icm(dev, key_to_hw_index(mr->key), GFP_KERNEL);
+       err = mlx4_mpt_alloc_icm(dev, key_to_hw_index(mr->key));
        if (err)
                return err;
 
@@ -787,14 +787,13 @@ int mlx4_write_mtt(struct mlx4_dev *dev, struct mlx4_mtt *mtt,
 EXPORT_SYMBOL_GPL(mlx4_write_mtt);
 
 int mlx4_buf_write_mtt(struct mlx4_dev *dev, struct mlx4_mtt *mtt,
-                      struct mlx4_buf *buf, gfp_t gfp)
+                      struct mlx4_buf *buf)
 {
        u64 *page_list;
        int err;
        int i;
 
-       page_list = kmalloc(buf->npages * sizeof *page_list,
-                           gfp);
+       page_list = kcalloc(buf->npages, sizeof(*page_list), GFP_KERNEL);
        if (!page_list)
                return -ENOMEM;
 
@@ -841,7 +840,7 @@ int mlx4_mw_enable(struct mlx4_dev *dev, struct mlx4_mw *mw)
        struct mlx4_mpt_entry *mpt_entry;
        int err;
 
-       err = mlx4_mpt_alloc_icm(dev, key_to_hw_index(mw->key), GFP_KERNEL);
+       err = mlx4_mpt_alloc_icm(dev, key_to_hw_index(mw->key));
        if (err)
                return err;
 
index 5a310d313e94d08d035c265e6b538c27dcf957c3..26747212526b074ea0fd4f8c6a0a274b34bb5033 100644 (file)
@@ -301,29 +301,29 @@ void mlx4_qp_release_range(struct mlx4_dev *dev, int base_qpn, int cnt)
 }
 EXPORT_SYMBOL_GPL(mlx4_qp_release_range);
 
-int __mlx4_qp_alloc_icm(struct mlx4_dev *dev, int qpn, gfp_t gfp)
+int __mlx4_qp_alloc_icm(struct mlx4_dev *dev, int qpn)
 {
        struct mlx4_priv *priv = mlx4_priv(dev);
        struct mlx4_qp_table *qp_table = &priv->qp_table;
        int err;
 
-       err = mlx4_table_get(dev, &qp_table->qp_table, qpn, gfp);
+       err = mlx4_table_get(dev, &qp_table->qp_table, qpn);
        if (err)
                goto err_out;
 
-       err = mlx4_table_get(dev, &qp_table->auxc_table, qpn, gfp);
+       err = mlx4_table_get(dev, &qp_table->auxc_table, qpn);
        if (err)
                goto err_put_qp;
 
-       err = mlx4_table_get(dev, &qp_table->altc_table, qpn, gfp);
+       err = mlx4_table_get(dev, &qp_table->altc_table, qpn);
        if (err)
                goto err_put_auxc;
 
-       err = mlx4_table_get(dev, &qp_table->rdmarc_table, qpn, gfp);
+       err = mlx4_table_get(dev, &qp_table->rdmarc_table, qpn);
        if (err)
                goto err_put_altc;
 
-       err = mlx4_table_get(dev, &qp_table->cmpt_table, qpn, gfp);
+       err = mlx4_table_get(dev, &qp_table->cmpt_table, qpn);
        if (err)
                goto err_put_rdmarc;
 
@@ -345,7 +345,7 @@ err_out:
        return err;
 }
 
-static int mlx4_qp_alloc_icm(struct mlx4_dev *dev, int qpn, gfp_t gfp)
+static int mlx4_qp_alloc_icm(struct mlx4_dev *dev, int qpn)
 {
        u64 param = 0;
 
@@ -355,7 +355,7 @@ static int mlx4_qp_alloc_icm(struct mlx4_dev *dev, int qpn, gfp_t gfp)
                                    MLX4_CMD_ALLOC_RES, MLX4_CMD_TIME_CLASS_A,
                                    MLX4_CMD_WRAPPED);
        }
-       return __mlx4_qp_alloc_icm(dev, qpn, gfp);
+       return __mlx4_qp_alloc_icm(dev, qpn);
 }
 
 void __mlx4_qp_free_icm(struct mlx4_dev *dev, int qpn)
@@ -397,7 +397,7 @@ struct mlx4_qp *mlx4_qp_lookup(struct mlx4_dev *dev, u32 qpn)
        return qp;
 }
 
-int mlx4_qp_alloc(struct mlx4_dev *dev, int qpn, struct mlx4_qp *qp, gfp_t gfp)
+int mlx4_qp_alloc(struct mlx4_dev *dev, int qpn, struct mlx4_qp *qp)
 {
        struct mlx4_priv *priv = mlx4_priv(dev);
        struct mlx4_qp_table *qp_table = &priv->qp_table;
@@ -408,7 +408,7 @@ int mlx4_qp_alloc(struct mlx4_dev *dev, int qpn, struct mlx4_qp *qp, gfp_t gfp)
 
        qp->qpn = qpn;
 
-       err = mlx4_qp_alloc_icm(dev, qpn, gfp);
+       err = mlx4_qp_alloc_icm(dev, qpn);
        if (err)
                return err;
 
index 812783865205715e8e88ad66d4ccbfe7172ec6e5..215e21c3dc8a8ac80bbf4e7fa0735bcb24c7df33 100644 (file)
@@ -1822,7 +1822,7 @@ static int qp_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd,
                        return err;
 
                if (!fw_reserved(dev, qpn)) {
-                       err = __mlx4_qp_alloc_icm(dev, qpn, GFP_KERNEL);
+                       err = __mlx4_qp_alloc_icm(dev, qpn);
                        if (err) {
                                res_abort_move(dev, slave, RES_QP, qpn);
                                return err;
@@ -1909,7 +1909,7 @@ static int mpt_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd,
                if (err)
                        return err;
 
-               err = __mlx4_mpt_alloc_icm(dev, mpt->key, GFP_KERNEL);
+               err = __mlx4_mpt_alloc_icm(dev, mpt->key);
                if (err) {
                        res_abort_move(dev, slave, RES_MPT, id);
                        return err;
index f44d089e2ca607e8b18cf46fdf0f713424171fe5..bedf5212682464651fe51d2a12a6ed41a8777f6d 100644 (file)
@@ -100,11 +100,11 @@ int __mlx4_srq_alloc_icm(struct mlx4_dev *dev, int *srqn)
        if (*srqn == -1)
                return -ENOMEM;
 
-       err = mlx4_table_get(dev, &srq_table->table, *srqn, GFP_KERNEL);
+       err = mlx4_table_get(dev, &srq_table->table, *srqn);
        if (err)
                goto err_out;
 
-       err = mlx4_table_get(dev, &srq_table->cmpt_table, *srqn, GFP_KERNEL);
+       err = mlx4_table_get(dev, &srq_table->cmpt_table, *srqn);
        if (err)
                goto err_put;
        return 0;
index 7cd99b1f8596b9856bf6c02bdddafcdd7910c21d..75bc08c6838ccebe1c01e3cec8e9fe0db0fba33d 100644 (file)
@@ -421,14 +421,15 @@ static void set_badblock(struct badblocks *bb, sector_t s, int num)
 static void __add_badblock_range(struct badblocks *bb, u64 ns_offset, u64 len)
 {
        const unsigned int sector_size = 512;
-       sector_t start_sector;
+       sector_t start_sector, end_sector;
        u64 num_sectors;
        u32 rem;
 
        start_sector = div_u64(ns_offset, sector_size);
-       num_sectors = div_u64_rem(len, sector_size, &rem);
+       end_sector = div_u64_rem(ns_offset + len, sector_size, &rem);
        if (rem)
-               num_sectors++;
+               end_sector++;
+       num_sectors = end_sector - start_sector;
 
        if (unlikely(num_sectors > (u64)INT_MAX)) {
                u64 remaining = num_sectors;
index 077f62e208aaef5125756ecd30273176698a7bc7..6a4367cc9caabea8f0bbc1519d309ab50b55578f 100644 (file)
@@ -3401,9 +3401,10 @@ static int cxlflash_afu_debug(struct cxlflash_cfg *cfg,
                if (is_write) {
                        req_flags |= SISL_REQ_FLAGS_HOST_WRITE;
 
-                       rc = copy_from_user(kbuf, ubuf, ulen);
-                       if (unlikely(rc))
+                       if (copy_from_user(kbuf, ubuf, ulen)) {
+                               rc = -EFAULT;
                                goto out;
+                       }
                }
        }
 
@@ -3431,8 +3432,10 @@ static int cxlflash_afu_debug(struct cxlflash_cfg *cfg,
                goto out;
        }
 
-       if (ulen && !is_write)
-               rc = copy_to_user(ubuf, kbuf, ulen);
+       if (ulen && !is_write) {
+               if (copy_to_user(ubuf, kbuf, ulen))
+                       rc = -EFAULT;
+       }
 out:
        kfree(buf);
        dev_dbg(dev, "%s: returning rc=%d\n", __func__, rc);
index 551d103c27f1303b5299e6d2ff80e8cd93b777ff..2bfea7082e3a070f0e6e44f27837df86b8f75c89 100644 (file)
@@ -1693,7 +1693,7 @@ static int prep_ssp_v2_hw(struct hisi_hba *hisi_hba,
 
 static int parse_trans_tx_err_code_v2_hw(u32 err_msk)
 {
-       const u8 trans_tx_err_code_prio[] = {
+       static const u8 trans_tx_err_code_prio[] = {
                TRANS_TX_OPEN_FAIL_WITH_IT_NEXUS_LOSS,
                TRANS_TX_ERR_PHY_NOT_ENABLE,
                TRANS_TX_OPEN_CNX_ERR_WRONG_DESTINATION,
@@ -1738,7 +1738,7 @@ static int parse_trans_tx_err_code_v2_hw(u32 err_msk)
 
 static int parse_trans_rx_err_code_v2_hw(u32 err_msk)
 {
-       const u8 trans_rx_err_code_prio[] = {
+       static const u8 trans_rx_err_code_prio[] = {
                TRANS_RX_ERR_WITH_RXFRAME_CRC_ERR,
                TRANS_RX_ERR_WITH_RXFIS_8B10B_DISP_ERR,
                TRANS_RX_ERR_WITH_RXFRAME_HAVE_ERRPRM,
@@ -1784,7 +1784,7 @@ static int parse_trans_rx_err_code_v2_hw(u32 err_msk)
 
 static int parse_dma_tx_err_code_v2_hw(u32 err_msk)
 {
-       const u8 dma_tx_err_code_prio[] = {
+       static const u8 dma_tx_err_code_prio[] = {
                DMA_TX_UNEXP_XFER_ERR,
                DMA_TX_UNEXP_RETRANS_ERR,
                DMA_TX_XFER_LEN_OVERFLOW,
@@ -1810,7 +1810,7 @@ static int parse_dma_tx_err_code_v2_hw(u32 err_msk)
 
 static int parse_sipc_rx_err_code_v2_hw(u32 err_msk)
 {
-       const u8 sipc_rx_err_code_prio[] = {
+       static const u8 sipc_rx_err_code_prio[] = {
                SIPC_RX_FIS_STATUS_ERR_BIT_VLD,
                SIPC_RX_PIO_WRSETUP_STATUS_DRQ_ERR,
                SIPC_RX_FIS_STATUS_BSY_BIT_ERR,
@@ -1836,7 +1836,7 @@ static int parse_sipc_rx_err_code_v2_hw(u32 err_msk)
 
 static int parse_dma_rx_err_code_v2_hw(u32 err_msk)
 {
-       const u8 dma_rx_err_code_prio[] = {
+       static const u8 dma_rx_err_code_prio[] = {
                DMA_RX_UNKNOWN_FRM_ERR,
                DMA_RX_DATA_LEN_OVERFLOW,
                DMA_RX_DATA_LEN_UNDERFLOW,
index 47f66e9497451e290112852fa5a3f6503b4f33eb..ed197bc8e801a604029ac12e93bf24d9bdce7e34 100644 (file)
@@ -213,7 +213,7 @@ static void sci_task_request_build_ssp_task_iu(struct isci_request *ireq)
  * @task_context:
  *
  */
-static void scu_ssp_reqeust_construct_task_context(
+static void scu_ssp_request_construct_task_context(
        struct isci_request *ireq,
        struct scu_task_context *task_context)
 {
@@ -425,7 +425,7 @@ static void scu_ssp_io_request_construct_task_context(struct isci_request *ireq,
        u8 prot_type = scsi_get_prot_type(scmd);
        u8 prot_op = scsi_get_prot_op(scmd);
 
-       scu_ssp_reqeust_construct_task_context(ireq, task_context);
+       scu_ssp_request_construct_task_context(ireq, task_context);
 
        task_context->ssp_command_iu_length =
                sizeof(struct ssp_cmd_iu) / sizeof(u32);
@@ -472,7 +472,7 @@ static void scu_ssp_task_request_construct_task_context(struct isci_request *ire
 {
        struct scu_task_context *task_context = ireq->tc;
 
-       scu_ssp_reqeust_construct_task_context(ireq, task_context);
+       scu_ssp_request_construct_task_context(ireq, task_context);
 
        task_context->control_frame                = 1;
        task_context->priority                     = SCU_TASK_PRIORITY_HIGH;
@@ -495,7 +495,7 @@ static void scu_ssp_task_request_construct_task_context(struct isci_request *ire
  * the command buffer is complete. none Revisit task context construction to
  * determine what is common for SSP/SMP/STP task context structures.
  */
-static void scu_sata_reqeust_construct_task_context(
+static void scu_sata_request_construct_task_context(
        struct isci_request *ireq,
        struct scu_task_context *task_context)
 {
@@ -562,7 +562,7 @@ static void scu_stp_raw_request_construct_task_context(struct isci_request *ireq
 {
        struct scu_task_context *task_context = ireq->tc;
 
-       scu_sata_reqeust_construct_task_context(ireq, task_context);
+       scu_sata_request_construct_task_context(ireq, task_context);
 
        task_context->control_frame         = 0;
        task_context->priority              = SCU_TASK_PRIORITY_NORMAL;
@@ -613,7 +613,7 @@ static void sci_stp_optimized_request_construct(struct isci_request *ireq,
        struct scu_task_context *task_context = ireq->tc;
 
        /* Build the STP task context structure */
-       scu_sata_reqeust_construct_task_context(ireq, task_context);
+       scu_sata_request_construct_task_context(ireq, task_context);
 
        /* Copy over the SGL elements */
        sci_request_build_sgl(ireq);
@@ -1401,7 +1401,7 @@ static enum sci_status sci_stp_request_pio_data_out_transmit_data(struct isci_re
  * @data_buffer: The buffer of data to be copied.
  * @length: The length of the data transfer.
  *
- * Copy the data from the buffer for the length specified to the IO reqeust SGL
+ * Copy the data from the buffer for the length specified to the IO request SGL
  * specified data region. enum sci_status
  */
 static enum sci_status
index fd501f8dbb1107fe7f567ec3e66cf7c9e6471083..8660f923ace02120eb63c2ac11724448d4cbd060 100644 (file)
@@ -573,7 +573,7 @@ static void fc_disc_gpn_ft_resp(struct fc_seq *sp, struct fc_frame *fp,
                event = DISC_EV_FAILED;
        }
        if (error)
-               fc_disc_error(disc, fp);
+               fc_disc_error(disc, ERR_PTR(error));
        else if (event != DISC_EV_NONE)
                fc_disc_done(disc, event);
        fc_frame_free(fp);
index b58bba4604e8cfce57fd320d53043bb293845765..7786c97e033fdcdd9643a41dd1d0bb928036d65b 100644 (file)
@@ -1227,7 +1227,7 @@ static void qedf_rport_event_handler(struct fc_lport *lport,
 
                if (rdata->spp_type != FC_TYPE_FCP) {
                        QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_DISC,
-                           "Not offlading since since spp type isn't FCP\n");
+                           "Not offloading since spp type isn't FCP\n");
                        break;
                }
                if (!(rdata->ids.roles & FC_RPORT_ROLE_FCP_TARGET)) {
index 32632c9b22766d59e223a256c430810a4fa33bec..91d2f51c351b4d6940d04a1e4a261f2d816e7b04 100644 (file)
 #include <linux/qed/qed_iscsi_if.h>
 #include <linux/qed/qed_ll2_if.h>
 #include "qedi_version.h"
+#include "qedi_nvm_iscsi_cfg.h"
 
 #define QEDI_MODULE_NAME               "qedi"
 
 struct qedi_endpoint;
 
+#ifndef GET_FIELD2
+#define GET_FIELD2(value, name) \
+       (((value) & (name ## _MASK)) >> (name ## _OFFSET))
+#endif
+
 /*
  * PCI function probe defines
  */
@@ -66,6 +72,11 @@ struct qedi_endpoint;
 #define QEDI_HW_DMA_BOUNDARY   0xfff
 #define QEDI_PATH_HANDLE       0xFE0000000UL
 
+enum qedi_nvm_tgts {
+       QEDI_NVM_TGT_PRI,
+       QEDI_NVM_TGT_SEC,
+};
+
 struct qedi_uio_ctrl {
        /* meta data */
        u32 uio_hsi_version;
@@ -283,6 +294,8 @@ struct qedi_ctx {
        void *bdq_pbl_list;
        dma_addr_t bdq_pbl_list_dma;
        u8 bdq_pbl_list_num_entries;
+       struct nvm_iscsi_cfg *iscsi_cfg;
+       dma_addr_t nvm_buf_dma;
        void __iomem *bdq_primary_prod;
        void __iomem *bdq_secondary_prod;
        u16 bdq_prod_idx;
@@ -337,6 +350,10 @@ struct qedi_ctx {
        bool use_fast_sge;
 
        atomic_t num_offloads;
+#define SYSFS_FLAG_FW_SEL_BOOT 2
+#define IPV6_LEN       41
+#define IPV4_LEN       17
+       struct iscsi_boot_kset *boot_kset;
 };
 
 struct qedi_work {
index 19254bd739d9c9e32b300d24fd418fc6f4ebd2b1..93d54acd4a22f70f7be57470056166f58ed69b0d 100644 (file)
@@ -1411,7 +1411,7 @@ static void qedi_tmf_work(struct work_struct *work)
 
        list_work = kzalloc(sizeof(*list_work), GFP_ATOMIC);
        if (!list_work) {
-               QEDI_ERR(&qedi->dbg_ctx, "Memory alloction failed\n");
+               QEDI_ERR(&qedi->dbg_ctx, "Memory allocation failed\n");
                goto abort_ret;
        }
 
index 5f5a4ef2e52965647e1e3db5b4cdd7bdb8021af8..2c37836848152f91b394bfeea4e120ce2d35f46a 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/mm.h>
 #include <linux/if_vlan.h>
 #include <linux/cpu.h>
+#include <linux/iscsi_boot_sysfs.h>
 
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_device.h>
@@ -1143,6 +1144,30 @@ exit_setup_int:
        return rc;
 }
 
+static void qedi_free_nvm_iscsi_cfg(struct qedi_ctx *qedi)
+{
+       if (qedi->iscsi_cfg)
+               dma_free_coherent(&qedi->pdev->dev,
+                                 sizeof(struct nvm_iscsi_cfg),
+                                 qedi->iscsi_cfg, qedi->nvm_buf_dma);
+}
+
+static int qedi_alloc_nvm_iscsi_cfg(struct qedi_ctx *qedi)
+{
+       qedi->iscsi_cfg = dma_zalloc_coherent(&qedi->pdev->dev,
+                                            sizeof(struct nvm_iscsi_cfg),
+                                            &qedi->nvm_buf_dma, GFP_KERNEL);
+       if (!qedi->iscsi_cfg) {
+               QEDI_ERR(&qedi->dbg_ctx, "Could not allocate NVM BUF.\n");
+               return -ENOMEM;
+       }
+       QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_INFO,
+                 "NVM BUF addr=0x%p dma=0x%llx.\n", qedi->iscsi_cfg,
+                 qedi->nvm_buf_dma);
+
+       return 0;
+}
+
 static void qedi_free_bdq(struct qedi_ctx *qedi)
 {
        int i;
@@ -1183,6 +1208,7 @@ static void qedi_free_global_queues(struct qedi_ctx *qedi)
                kfree(gl[i]);
        }
        qedi_free_bdq(qedi);
+       qedi_free_nvm_iscsi_cfg(qedi);
 }
 
 static int qedi_alloc_bdq(struct qedi_ctx *qedi)
@@ -1309,6 +1335,11 @@ static int qedi_alloc_global_queues(struct qedi_ctx *qedi)
        if (rc)
                goto mem_alloc_failure;
 
+       /* Allocate DMA coherent buffers for NVM_ISCSI_CFG */
+       rc = qedi_alloc_nvm_iscsi_cfg(qedi);
+       if (rc)
+               goto mem_alloc_failure;
+
        /* Allocate a CQ and an associated PBL for each MSI-X
         * vector.
         */
@@ -1671,6 +1702,387 @@ void qedi_reset_host_mtu(struct qedi_ctx *qedi, u16 mtu)
        qedi_ops->ll2->start(qedi->cdev, &params);
 }
 
+/**
+ * qedi_get_nvram_block: - Scan through the iSCSI NVRAM block (while accounting
+ * for gaps) for the matching absolute-pf-id of the QEDI device.
+ */
+static struct nvm_iscsi_block *
+qedi_get_nvram_block(struct qedi_ctx *qedi)
+{
+       int i;
+       u8 pf;
+       u32 flags;
+       struct nvm_iscsi_block *block;
+
+       pf = qedi->dev_info.common.abs_pf_id;
+       block = &qedi->iscsi_cfg->block[0];
+       for (i = 0; i < NUM_OF_ISCSI_PF_SUPPORTED; i++, block++) {
+               flags = ((block->id) & NVM_ISCSI_CFG_BLK_CTRL_FLAG_MASK) >>
+                       NVM_ISCSI_CFG_BLK_CTRL_FLAG_OFFSET;
+               if (flags & (NVM_ISCSI_CFG_BLK_CTRL_FLAG_IS_NOT_EMPTY |
+                               NVM_ISCSI_CFG_BLK_CTRL_FLAG_PF_MAPPED) &&
+                       (pf == (block->id & NVM_ISCSI_CFG_BLK_MAPPED_PF_ID_MASK)
+                               >> NVM_ISCSI_CFG_BLK_MAPPED_PF_ID_OFFSET))
+                       return block;
+       }
+       return NULL;
+}
+
+static ssize_t qedi_show_boot_eth_info(void *data, int type, char *buf)
+{
+       struct qedi_ctx *qedi = data;
+       struct nvm_iscsi_initiator *initiator;
+       char *str = buf;
+       int rc = 1;
+       u32 ipv6_en, dhcp_en, ip_len;
+       struct nvm_iscsi_block *block;
+       char *fmt, *ip, *sub, *gw;
+
+       block = qedi_get_nvram_block(qedi);
+       if (!block)
+               return 0;
+
+       initiator = &block->initiator;
+       ipv6_en = block->generic.ctrl_flags &
+                 NVM_ISCSI_CFG_GEN_IPV6_ENABLED;
+       dhcp_en = block->generic.ctrl_flags &
+                 NVM_ISCSI_CFG_GEN_DHCP_TCPIP_CONFIG_ENABLED;
+       /* Static IP assignments. */
+       fmt = ipv6_en ? "%pI6\n" : "%pI4\n";
+       ip = ipv6_en ? initiator->ipv6.addr.byte : initiator->ipv4.addr.byte;
+       ip_len = ipv6_en ? IPV6_LEN : IPV4_LEN;
+       sub = ipv6_en ? initiator->ipv6.subnet_mask.byte :
+             initiator->ipv4.subnet_mask.byte;
+       gw = ipv6_en ? initiator->ipv6.gateway.byte :
+            initiator->ipv4.gateway.byte;
+       /* DHCP IP adjustments. */
+       fmt = dhcp_en ? "%s\n" : fmt;
+       if (dhcp_en) {
+               ip = ipv6_en ? "0::0" : "0.0.0.0";
+               sub = ip;
+               gw = ip;
+               ip_len = ipv6_en ? 5 : 8;
+       }
+
+       switch (type) {
+       case ISCSI_BOOT_ETH_IP_ADDR:
+               rc = snprintf(str, ip_len, fmt, ip);
+               break;
+       case ISCSI_BOOT_ETH_SUBNET_MASK:
+               rc = snprintf(str, ip_len, fmt, sub);
+               break;
+       case ISCSI_BOOT_ETH_GATEWAY:
+               rc = snprintf(str, ip_len, fmt, gw);
+               break;
+       case ISCSI_BOOT_ETH_FLAGS:
+               rc = snprintf(str, 3, "%hhd\n",
+                             SYSFS_FLAG_FW_SEL_BOOT);
+               break;
+       case ISCSI_BOOT_ETH_INDEX:
+               rc = snprintf(str, 3, "0\n");
+               break;
+       case ISCSI_BOOT_ETH_MAC:
+               rc = sysfs_format_mac(str, qedi->mac, ETH_ALEN);
+               break;
+       case ISCSI_BOOT_ETH_VLAN:
+               rc = snprintf(str, 12, "%d\n",
+                             GET_FIELD2(initiator->generic_cont0,
+                                        NVM_ISCSI_CFG_INITIATOR_VLAN));
+               break;
+       case ISCSI_BOOT_ETH_ORIGIN:
+               if (dhcp_en)
+                       rc = snprintf(str, 3, "3\n");
+               break;
+       default:
+               rc = 0;
+               break;
+       }
+
+       return rc;
+}
+
+static umode_t qedi_eth_get_attr_visibility(void *data, int type)
+{
+       int rc = 1;
+
+       switch (type) {
+       case ISCSI_BOOT_ETH_FLAGS:
+       case ISCSI_BOOT_ETH_MAC:
+       case ISCSI_BOOT_ETH_INDEX:
+       case ISCSI_BOOT_ETH_IP_ADDR:
+       case ISCSI_BOOT_ETH_SUBNET_MASK:
+       case ISCSI_BOOT_ETH_GATEWAY:
+       case ISCSI_BOOT_ETH_ORIGIN:
+       case ISCSI_BOOT_ETH_VLAN:
+               rc = 0444;
+               break;
+       default:
+               rc = 0;
+               break;
+       }
+       return rc;
+}
+
+static ssize_t qedi_show_boot_ini_info(void *data, int type, char *buf)
+{
+       struct qedi_ctx *qedi = data;
+       struct nvm_iscsi_initiator *initiator;
+       char *str = buf;
+       int rc;
+       struct nvm_iscsi_block *block;
+
+       block = qedi_get_nvram_block(qedi);
+       if (!block)
+               return 0;
+
+       initiator = &block->initiator;
+
+       switch (type) {
+       case ISCSI_BOOT_INI_INITIATOR_NAME:
+               rc = snprintf(str, NVM_ISCSI_CFG_ISCSI_NAME_MAX_LEN, "%s\n",
+                             initiator->initiator_name.byte);
+               break;
+       default:
+               rc = 0;
+               break;
+       }
+       return rc;
+}
+
+static umode_t qedi_ini_get_attr_visibility(void *data, int type)
+{
+       int rc;
+
+       switch (type) {
+       case ISCSI_BOOT_INI_INITIATOR_NAME:
+               rc = 0444;
+               break;
+       default:
+               rc = 0;
+               break;
+       }
+       return rc;
+}
+
+static ssize_t
+qedi_show_boot_tgt_info(struct qedi_ctx *qedi, int type,
+                       char *buf, enum qedi_nvm_tgts idx)
+{
+       char *str = buf;
+       int rc = 1;
+       u32 ctrl_flags, ipv6_en, chap_en, mchap_en, ip_len;
+       struct nvm_iscsi_block *block;
+       char *chap_name, *chap_secret;
+       char *mchap_name, *mchap_secret;
+
+       block = qedi_get_nvram_block(qedi);
+       if (!block)
+               goto exit_show_tgt_info;
+
+       QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_EVT,
+                 "Port:%d, tgt_idx:%d\n",
+                 GET_FIELD2(block->id, NVM_ISCSI_CFG_BLK_MAPPED_PF_ID), idx);
+
+       ctrl_flags = block->target[idx].ctrl_flags &
+                    NVM_ISCSI_CFG_TARGET_ENABLED;
+
+       if (!ctrl_flags) {
+               QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_EVT,
+                         "Target disabled\n");
+               goto exit_show_tgt_info;
+       }
+
+       ipv6_en = block->generic.ctrl_flags &
+                 NVM_ISCSI_CFG_GEN_IPV6_ENABLED;
+       ip_len = ipv6_en ? IPV6_LEN : IPV4_LEN;
+       chap_en = block->generic.ctrl_flags &
+                 NVM_ISCSI_CFG_GEN_CHAP_ENABLED;
+       chap_name = chap_en ? block->initiator.chap_name.byte : NULL;
+       chap_secret = chap_en ? block->initiator.chap_password.byte : NULL;
+
+       mchap_en = block->generic.ctrl_flags &
+                 NVM_ISCSI_CFG_GEN_CHAP_MUTUAL_ENABLED;
+       mchap_name = mchap_en ? block->target[idx].chap_name.byte : NULL;
+       mchap_secret = mchap_en ? block->target[idx].chap_password.byte : NULL;
+
+       switch (type) {
+       case ISCSI_BOOT_TGT_NAME:
+               rc = snprintf(str, NVM_ISCSI_CFG_ISCSI_NAME_MAX_LEN, "%s\n",
+                             block->target[idx].target_name.byte);
+               break;
+       case ISCSI_BOOT_TGT_IP_ADDR:
+               if (ipv6_en)
+                       rc = snprintf(str, ip_len, "%pI6\n",
+                                     block->target[idx].ipv6_addr.byte);
+               else
+                       rc = snprintf(str, ip_len, "%pI4\n",
+                                     block->target[idx].ipv4_addr.byte);
+               break;
+       case ISCSI_BOOT_TGT_PORT:
+               rc = snprintf(str, 12, "%d\n",
+                             GET_FIELD2(block->target[idx].generic_cont0,
+                                        NVM_ISCSI_CFG_TARGET_TCP_PORT));
+               break;
+       case ISCSI_BOOT_TGT_LUN:
+               rc = snprintf(str, 22, "%.*d\n",
+                             block->target[idx].lun.value[1],
+                             block->target[idx].lun.value[0]);
+               break;
+       case ISCSI_BOOT_TGT_CHAP_NAME:
+               rc = snprintf(str, NVM_ISCSI_CFG_CHAP_NAME_MAX_LEN, "%s\n",
+                             chap_name);
+               break;
+       case ISCSI_BOOT_TGT_CHAP_SECRET:
+               rc = snprintf(str, NVM_ISCSI_CFG_CHAP_PWD_MAX_LEN, "%s\n",
+                             chap_secret);
+               break;
+       case ISCSI_BOOT_TGT_REV_CHAP_NAME:
+               rc = snprintf(str, NVM_ISCSI_CFG_CHAP_NAME_MAX_LEN, "%s\n",
+                             mchap_name);
+               break;
+       case ISCSI_BOOT_TGT_REV_CHAP_SECRET:
+               rc = snprintf(str, NVM_ISCSI_CFG_CHAP_PWD_MAX_LEN, "%s\n",
+                             mchap_secret);
+               break;
+       case ISCSI_BOOT_TGT_FLAGS:
+               rc = snprintf(str, 3, "%hhd\n", SYSFS_FLAG_FW_SEL_BOOT);
+               break;
+       case ISCSI_BOOT_TGT_NIC_ASSOC:
+               rc = snprintf(str, 3, "0\n");
+               break;
+       default:
+               rc = 0;
+               break;
+       }
+
+exit_show_tgt_info:
+       return rc;
+}
+
+static ssize_t qedi_show_boot_tgt_pri_info(void *data, int type, char *buf)
+{
+       struct qedi_ctx *qedi = data;
+
+       return qedi_show_boot_tgt_info(qedi, type, buf, QEDI_NVM_TGT_PRI);
+}
+
+static ssize_t qedi_show_boot_tgt_sec_info(void *data, int type, char *buf)
+{
+       struct qedi_ctx *qedi = data;
+
+       return qedi_show_boot_tgt_info(qedi, type, buf, QEDI_NVM_TGT_SEC);
+}
+
+static umode_t qedi_tgt_get_attr_visibility(void *data, int type)
+{
+       int rc;
+
+       switch (type) {
+       case ISCSI_BOOT_TGT_NAME:
+       case ISCSI_BOOT_TGT_IP_ADDR:
+       case ISCSI_BOOT_TGT_PORT:
+       case ISCSI_BOOT_TGT_LUN:
+       case ISCSI_BOOT_TGT_CHAP_NAME:
+       case ISCSI_BOOT_TGT_CHAP_SECRET:
+       case ISCSI_BOOT_TGT_REV_CHAP_NAME:
+       case ISCSI_BOOT_TGT_REV_CHAP_SECRET:
+       case ISCSI_BOOT_TGT_NIC_ASSOC:
+       case ISCSI_BOOT_TGT_FLAGS:
+               rc = 0444;
+               break;
+       default:
+               rc = 0;
+               break;
+       }
+       return rc;
+}
+
+static void qedi_boot_release(void *data)
+{
+       struct qedi_ctx *qedi = data;
+
+       scsi_host_put(qedi->shost);
+}
+
+static int qedi_get_boot_info(struct qedi_ctx *qedi)
+{
+       int ret = 1;
+       u16 len;
+
+       len = sizeof(struct nvm_iscsi_cfg);
+
+       QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_INFO,
+                 "Get NVM iSCSI CFG image\n");
+       ret = qedi_ops->common->nvm_get_image(qedi->cdev,
+                                             QED_NVM_IMAGE_ISCSI_CFG,
+                                             (char *)qedi->iscsi_cfg, len);
+       if (ret)
+               QEDI_ERR(&qedi->dbg_ctx,
+                        "Could not get NVM image. ret = %d\n", ret);
+
+       return ret;
+}
+
+static int qedi_setup_boot_info(struct qedi_ctx *qedi)
+{
+       struct iscsi_boot_kobj *boot_kobj;
+
+       if (qedi_get_boot_info(qedi))
+               return -EPERM;
+
+       qedi->boot_kset = iscsi_boot_create_host_kset(qedi->shost->host_no);
+       if (!qedi->boot_kset)
+               goto kset_free;
+
+       if (!scsi_host_get(qedi->shost))
+               goto kset_free;
+
+       boot_kobj = iscsi_boot_create_target(qedi->boot_kset, 0, qedi,
+                                            qedi_show_boot_tgt_pri_info,
+                                            qedi_tgt_get_attr_visibility,
+                                            qedi_boot_release);
+       if (!boot_kobj)
+               goto put_host;
+
+       if (!scsi_host_get(qedi->shost))
+               goto kset_free;
+
+       boot_kobj = iscsi_boot_create_target(qedi->boot_kset, 1, qedi,
+                                            qedi_show_boot_tgt_sec_info,
+                                            qedi_tgt_get_attr_visibility,
+                                            qedi_boot_release);
+       if (!boot_kobj)
+               goto put_host;
+
+       if (!scsi_host_get(qedi->shost))
+               goto kset_free;
+
+       boot_kobj = iscsi_boot_create_initiator(qedi->boot_kset, 0, qedi,
+                                               qedi_show_boot_ini_info,
+                                               qedi_ini_get_attr_visibility,
+                                               qedi_boot_release);
+       if (!boot_kobj)
+               goto put_host;
+
+       if (!scsi_host_get(qedi->shost))
+               goto kset_free;
+
+       boot_kobj = iscsi_boot_create_ethernet(qedi->boot_kset, 0, qedi,
+                                              qedi_show_boot_eth_info,
+                                              qedi_eth_get_attr_visibility,
+                                              qedi_boot_release);
+       if (!boot_kobj)
+               goto put_host;
+
+       return 0;
+
+put_host:
+       scsi_host_put(qedi->shost);
+kset_free:
+       iscsi_boot_destroy_kset(qedi->boot_kset);
+       return -ENOMEM;
+}
+
 static void __qedi_remove(struct pci_dev *pdev, int mode)
 {
        struct qedi_ctx *qedi = pci_get_drvdata(pdev);
@@ -1724,6 +2136,9 @@ static void __qedi_remove(struct pci_dev *pdev, int mode)
                        qedi->ll2_recv_thread = NULL;
                }
                qedi_ll2_free_skbs(qedi);
+
+               if (qedi->boot_kset)
+                       iscsi_boot_destroy_kset(qedi->boot_kset);
        }
 }
 
@@ -1967,6 +2382,10 @@ static int __qedi_probe(struct pci_dev *pdev, int mode)
                /* F/w needs 1st task context memory entry for performance */
                set_bit(QEDI_RESERVE_TASK_ID, qedi->task_idx_map);
                atomic_set(&qedi->num_offloads, 0);
+
+               if (qedi_setup_boot_info(qedi))
+                       QEDI_ERR(&qedi->dbg_ctx,
+                                "No iSCSI boot target configured\n");
        }
 
        return 0;
diff --git a/drivers/scsi/qedi/qedi_nvm_iscsi_cfg.h b/drivers/scsi/qedi/qedi_nvm_iscsi_cfg.h
new file mode 100644 (file)
index 0000000..df39b69
--- /dev/null
@@ -0,0 +1,210 @@
+/*
+ * QLogic iSCSI Offload Driver
+ * Copyright (c) 2016 Cavium Inc.
+ *
+ * This software is available under the terms of the GNU General Public License
+ * (GPL) Version 2, available from the file COPYING in the main directory of
+ * this source tree.
+ */
+
+#ifndef NVM_ISCSI_CFG_H
+#define NVM_ISCSI_CFG_H
+
+#define NUM_OF_ISCSI_TARGET_PER_PF    4   /* Defined as per the
+                                          * ISCSI IBFT constraint
+                                          */
+#define NUM_OF_ISCSI_PF_SUPPORTED     4   /* One PF per Port -
+                                          * assuming 4 port card
+                                          */
+
+#define NVM_ISCSI_CFG_DHCP_NAME_MAX_LEN  256
+
+union nvm_iscsi_dhcp_vendor_id {
+       u32 value[NVM_ISCSI_CFG_DHCP_NAME_MAX_LEN / 4];
+       u8  byte[NVM_ISCSI_CFG_DHCP_NAME_MAX_LEN];
+};
+
+#define NVM_ISCSI_IPV4_ADDR_BYTE_LEN 4
+union nvm_iscsi_ipv4_addr {
+       u32 addr;
+       u8  byte[NVM_ISCSI_IPV4_ADDR_BYTE_LEN];
+};
+
+#define NVM_ISCSI_IPV6_ADDR_BYTE_LEN 16
+union nvm_iscsi_ipv6_addr {
+       u32 addr[4];
+       u8  byte[NVM_ISCSI_IPV6_ADDR_BYTE_LEN];
+};
+
+struct nvm_iscsi_initiator_ipv4 {
+       union nvm_iscsi_ipv4_addr addr;                         /* 0x0 */
+       union nvm_iscsi_ipv4_addr subnet_mask;                  /* 0x4 */
+       union nvm_iscsi_ipv4_addr gateway;                      /* 0x8 */
+       union nvm_iscsi_ipv4_addr primary_dns;                  /* 0xC */
+       union nvm_iscsi_ipv4_addr secondary_dns;                /* 0x10 */
+       union nvm_iscsi_ipv4_addr dhcp_addr;                    /* 0x14 */
+
+       union nvm_iscsi_ipv4_addr isns_server;                  /* 0x18 */
+       union nvm_iscsi_ipv4_addr slp_server;                   /* 0x1C */
+       union nvm_iscsi_ipv4_addr primay_radius_server;         /* 0x20 */
+       union nvm_iscsi_ipv4_addr secondary_radius_server;      /* 0x24 */
+
+       union nvm_iscsi_ipv4_addr rsvd[4];                      /* 0x28 */
+};
+
+struct nvm_iscsi_initiator_ipv6 {
+       union nvm_iscsi_ipv6_addr addr;                         /* 0x0 */
+       union nvm_iscsi_ipv6_addr subnet_mask;                  /* 0x10 */
+       union nvm_iscsi_ipv6_addr gateway;                      /* 0x20 */
+       union nvm_iscsi_ipv6_addr primary_dns;                  /* 0x30 */
+       union nvm_iscsi_ipv6_addr secondary_dns;                /* 0x40 */
+       union nvm_iscsi_ipv6_addr dhcp_addr;                    /* 0x50 */
+
+       union nvm_iscsi_ipv6_addr isns_server;                  /* 0x60 */
+       union nvm_iscsi_ipv6_addr slp_server;                   /* 0x70 */
+       union nvm_iscsi_ipv6_addr primay_radius_server;         /* 0x80 */
+       union nvm_iscsi_ipv6_addr secondary_radius_server;      /* 0x90 */
+
+       union nvm_iscsi_ipv6_addr rsvd[3];                      /* 0xA0 */
+
+       u32   config;                                           /* 0xD0 */
+#define NVM_ISCSI_CFG_INITIATOR_IPV6_SUBNET_MASK_PREFIX_MASK      0x000000FF
+#define NVM_ISCSI_CFG_INITIATOR_IPV6_SUBNET_MASK_PREFIX_OFFSET    0
+
+       u32   rsvd_1[3];
+};
+
+#define NVM_ISCSI_CFG_ISCSI_NAME_MAX_LEN  256
+union nvm_iscsi_name {
+       u32 value[NVM_ISCSI_CFG_ISCSI_NAME_MAX_LEN / 4];
+       u8  byte[NVM_ISCSI_CFG_ISCSI_NAME_MAX_LEN];
+};
+
+#define NVM_ISCSI_CFG_CHAP_NAME_MAX_LEN  256
+union nvm_iscsi_chap_name {
+       u32 value[NVM_ISCSI_CFG_CHAP_NAME_MAX_LEN / 4];
+       u8  byte[NVM_ISCSI_CFG_CHAP_NAME_MAX_LEN];
+};
+
+#define NVM_ISCSI_CFG_CHAP_PWD_MAX_LEN  16 /* md5 need per RFC1996
+                                           * is 16 octets
+                                           */
+union nvm_iscsi_chap_password {
+       u32 value[NVM_ISCSI_CFG_CHAP_PWD_MAX_LEN / 4];
+       u8 byte[NVM_ISCSI_CFG_CHAP_PWD_MAX_LEN];
+};
+
+union nvm_iscsi_lun {
+       u8  byte[8];
+       u32 value[2];
+};
+
+struct nvm_iscsi_generic {
+       u32 ctrl_flags;                                         /* 0x0 */
+#define NVM_ISCSI_CFG_GEN_CHAP_ENABLED                 BIT(0)
+#define NVM_ISCSI_CFG_GEN_DHCP_TCPIP_CONFIG_ENABLED    BIT(1)
+#define NVM_ISCSI_CFG_GEN_DHCP_ISCSI_CONFIG_ENABLED    BIT(2)
+#define NVM_ISCSI_CFG_GEN_IPV6_ENABLED                 BIT(3)
+#define NVM_ISCSI_CFG_GEN_IPV4_FALLBACK_ENABLED        BIT(4)
+#define NVM_ISCSI_CFG_GEN_ISNS_WORLD_LOGIN             BIT(5)
+#define NVM_ISCSI_CFG_GEN_ISNS_SELECTIVE_LOGIN         BIT(6)
+#define NVM_ISCSI_CFG_GEN_ADDR_REDIRECT_ENABLED               BIT(7)
+#define NVM_ISCSI_CFG_GEN_CHAP_MUTUAL_ENABLED          BIT(8)
+
+       u32 timeout;                                            /* 0x4 */
+#define NVM_ISCSI_CFG_GEN_DHCP_REQUEST_TIMEOUT_MASK       0x0000FFFF
+#define NVM_ISCSI_CFG_GEN_DHCP_REQUEST_TIMEOUT_OFFSET     0
+#define NVM_ISCSI_CFG_GEN_PORT_LOGIN_TIMEOUT_MASK         0xFFFF0000
+#define NVM_ISCSI_CFG_GEN_PORT_LOGIN_TIMEOUT_OFFSET       16
+
+       union nvm_iscsi_dhcp_vendor_id  dhcp_vendor_id;         /* 0x8  */
+       u32 rsvd[62];                                           /* 0x108 */
+};
+
+struct nvm_iscsi_initiator {
+       struct nvm_iscsi_initiator_ipv4 ipv4;                   /* 0x0 */
+       struct nvm_iscsi_initiator_ipv6 ipv6;                   /* 0x38 */
+
+       union nvm_iscsi_name           initiator_name;          /* 0x118 */
+       union nvm_iscsi_chap_name      chap_name;               /* 0x218 */
+       union nvm_iscsi_chap_password  chap_password;           /* 0x318 */
+
+       u32 generic_cont0;                                      /* 0x398 */
+#define NVM_ISCSI_CFG_INITIATOR_VLAN_MASK              0x0000FFFF
+#define NVM_ISCSI_CFG_INITIATOR_VLAN_OFFSET            0
+#define NVM_ISCSI_CFG_INITIATOR_IP_VERSION_MASK                0x00030000
+#define NVM_ISCSI_CFG_INITIATOR_IP_VERSION_OFFSET      16
+#define NVM_ISCSI_CFG_INITIATOR_IP_VERSION_4           1
+#define NVM_ISCSI_CFG_INITIATOR_IP_VERSION_6           2
+#define NVM_ISCSI_CFG_INITIATOR_IP_VERSION_4_AND_6     3
+
+       u32 ctrl_flags;
+#define NVM_ISCSI_CFG_INITIATOR_IP_VERSION_PRIORITY_V6     BIT(0)
+#define NVM_ISCSI_CFG_INITIATOR_VLAN_ENABLED               BIT(1)
+
+       u32 rsvd[116];                                          /* 0x32C */
+};
+
+struct nvm_iscsi_target {
+       u32 ctrl_flags;                                         /* 0x0 */
+#define NVM_ISCSI_CFG_TARGET_ENABLED            BIT(0)
+#define NVM_ISCSI_CFG_BOOT_TIME_LOGIN_STATUS    BIT(1)
+
+       u32 generic_cont0;                                      /* 0x4 */
+#define NVM_ISCSI_CFG_TARGET_TCP_PORT_MASK      0x0000FFFF
+#define NVM_ISCSI_CFG_TARGET_TCP_PORT_OFFSET    0
+
+       u32 ip_ver;
+#define NVM_ISCSI_CFG_IPv4       4
+#define NVM_ISCSI_CFG_IPv6       6
+
+       u32 rsvd_1[7];                                          /* 0x24 */
+       union nvm_iscsi_ipv4_addr ipv4_addr;                    /* 0x28 */
+       union nvm_iscsi_ipv6_addr ipv6_addr;                    /* 0x2C */
+       union nvm_iscsi_lun lun;                                /* 0x3C */
+
+       union nvm_iscsi_name           target_name;             /* 0x44 */
+       union nvm_iscsi_chap_name      chap_name;               /* 0x144 */
+       union nvm_iscsi_chap_password  chap_password;           /* 0x244 */
+
+       u32 rsvd_2[107];                                        /* 0x2C4 */
+};
+
+struct nvm_iscsi_block {
+       u32 id;                                                 /* 0x0 */
+#define NVM_ISCSI_CFG_BLK_MAPPED_PF_ID_MASK         0x0000000F
+#define NVM_ISCSI_CFG_BLK_MAPPED_PF_ID_OFFSET       0
+#define NVM_ISCSI_CFG_BLK_CTRL_FLAG_MASK            0x00000FF0
+#define NVM_ISCSI_CFG_BLK_CTRL_FLAG_OFFSET          4
+#define NVM_ISCSI_CFG_BLK_CTRL_FLAG_IS_NOT_EMPTY    BIT(0)
+#define NVM_ISCSI_CFG_BLK_CTRL_FLAG_PF_MAPPED       BIT(1)
+
+       u32 rsvd_1[5];                                          /* 0x4 */
+
+       struct nvm_iscsi_generic     generic;                   /* 0x18 */
+       struct nvm_iscsi_initiator   initiator;                 /* 0x218 */
+       struct nvm_iscsi_target      target[NUM_OF_ISCSI_TARGET_PER_PF];
+                                                               /* 0x718 */
+
+       u32 rsvd_2[58];                                         /* 0x1718 */
+       /* total size - 0x1800 - 6K block */
+};
+
+struct nvm_iscsi_cfg {
+       u32 id;                                                 /* 0x0 */
+#define NVM_ISCSI_CFG_BLK_VERSION_MINOR_MASK     0x000000FF
+#define NVM_ISCSI_CFG_BLK_VERSION_MAJOR_MASK     0x0000FF00
+#define NVM_ISCSI_CFG_BLK_SIGNATURE_MASK         0xFFFF0000
+#define NVM_ISCSI_CFG_BLK_SIGNATURE              0x49430000 /* IC - Iscsi
+                                                            * Config
+                                                            */
+
+#define NVM_ISCSI_CFG_BLK_VERSION_MAJOR          0
+#define NVM_ISCSI_CFG_BLK_VERSION_MINOR          10
+#define NVM_ISCSI_CFG_BLK_VERSION ((NVM_ISCSI_CFG_BLK_VERSION_MAJOR << 8) | \
+                                  NVM_ISCSI_CFG_BLK_VERSION_MINOR)
+
+       struct nvm_iscsi_block  block[NUM_OF_ISCSI_PF_SUPPORTED]; /* 0x4 */
+};
+
+#endif
index c2dc836dc4843e79ad6239186b650a14f1f91693..e101cd3043b94539a2893e77aa9949c8fd9c7acb 100644 (file)
@@ -3727,7 +3727,7 @@ static struct qla_tgt_cmd *qlt_ctio_to_cmd(struct scsi_qla_host *vha,
        h &= QLA_CMD_HANDLE_MASK;
 
        if (h != QLA_TGT_NULL_HANDLE) {
-               if (unlikely(h > req->num_outstanding_cmds)) {
+               if (unlikely(h >= req->num_outstanding_cmds)) {
                        ql_dbg(ql_dbg_tgt, vha, 0xe052,
                            "qla_target(%d): Wrong handle %x received\n",
                            vha->vp_idx, handle);
index 21225d62b0c1f4424bc72f57f8daf109cabffb7e..1e82d4128a84800d3f96011c49e0b3fc12c55d8e 100644 (file)
@@ -758,8 +758,11 @@ static bool sg_is_valid_dxfer(sg_io_hdr_t *hp)
                if (hp->dxferp || hp->dxfer_len > 0)
                        return false;
                return true;
-       case SG_DXFER_TO_DEV:
        case SG_DXFER_FROM_DEV:
+               if (hp->dxfer_len < 0)
+                       return false;
+               return true;
+       case SG_DXFER_TO_DEV:
        case SG_DXFER_TO_FROM_DEV:
                if (!hp->dxferp || hp->dxfer_len == 0)
                        return false;
index 8b93197daefe33c2330377dcac7dcf6d8c46c048..9be211d68b1596b4a9b482fa4e17888b6f559e39 100644 (file)
@@ -837,6 +837,7 @@ static struct scsi_host_template virtscsi_host_template_multi = {
        .eh_abort_handler = virtscsi_abort,
        .eh_device_reset_handler = virtscsi_device_reset,
        .eh_timed_out = virtscsi_eh_timed_out,
+       .slave_alloc = virtscsi_device_alloc,
 
        .can_queue = 1024,
        .dma_boundary = UINT_MAX,
index 69ec23daa25e003ff94ef306c93a0a77c51b00a3..a1e6860b6f46a091e28855eb5b6ed48c937aebac 100644 (file)
@@ -574,7 +574,7 @@ static int load_flat_file(struct linux_binprm *bprm,
                                MAX_SHARED_LIBS * sizeof(unsigned long),
                                FLAT_DATA_ALIGN);
 
-               pr_debug("Allocated data+bss+stack (%ld bytes): %lx\n",
+               pr_debug("Allocated data+bss+stack (%u bytes): %lx\n",
                         data_len + bss_len + stack_len, datapos);
 
                fpos = ntohl(hdr->data_start);
index e071d23f61481bf23fc4407d72ea75c9d1ec2430..ef7240ace5767a0439f9eab941725b900281e844 100644 (file)
@@ -271,6 +271,11 @@ out:
                if (ret < 0)
                        err = ret;
                dput(last);
+               /* last_name no longer match cache index */
+               if (fi->readdir_cache_idx >= 0) {
+                       fi->readdir_cache_idx = -1;
+                       fi->dir_release_count = 0;
+               }
        }
        return err;
 }
index de45d9e7674878db78d77d9aa4ac09e8da429dd9..6790767d18834fcb71b360f6683fe2cf54edb42f 100644 (file)
@@ -16,7 +16,7 @@ struct mnt_namespace {
        u64 event;
        unsigned int            mounts; /* # of mounts in the namespace */
        unsigned int            pending_mounts;
-};
+} __randomize_layout;
 
 struct mnt_pcp {
        int mnt_count;
@@ -69,7 +69,7 @@ struct mount {
        struct hlist_head mnt_pins;
        struct fs_pin mnt_umount;
        struct dentry *mnt_ex_mountpoint;
-};
+} __randomize_layout;
 
 #define MNT_NS_INTERNAL ERR_PTR(-EINVAL) /* distinct from any mnt_namespace */
 
index 88fd38d1e3e7ae8b9a6e0df2ea4baedb0c423cfa..ddb6a7c2b3d4aee1c3512e064350822533968dc5 100644 (file)
@@ -524,7 +524,7 @@ struct nameidata {
        struct inode    *link_inode;
        unsigned        root_seq;
        int             dfd;
-};
+} __randomize_layout;
 
 static void set_nameidata(struct nameidata *p, int dfd, struct filename *name)
 {
index b45083c0f9ae8a78838d84145f71efaf1eab4d89..49b0a9e7ff18bb70d8be183718c598eb90009a49 100644 (file)
@@ -720,8 +720,8 @@ static const struct rpc_version nfs_cb_version4 = {
        .counts                 = nfs4_cb_counts,
 };
 
-static const struct rpc_version *nfs_cb_version[] = {
-       &nfs_cb_version4,
+static const struct rpc_version *nfs_cb_version[2] = {
+       [1] = &nfs_cb_version4,
 };
 
 static const struct rpc_program cb_program;
@@ -795,7 +795,7 @@ static int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *c
                .saddress       = (struct sockaddr *) &conn->cb_saddr,
                .timeout        = &timeparms,
                .program        = &cb_program,
-               .version        = 0,
+               .version        = 1,
                .flags          = (RPC_CLNT_CREATE_NOPING | RPC_CLNT_CREATE_QUIET),
        };
        struct rpc_clnt *client;
index 18694598bebfb4781c79cb9c75107f37e54349c4..aa2b8907163086daf83034a3dcf54b011d794fe9 100644 (file)
@@ -51,7 +51,7 @@ struct proc_dir_entry {
        spinlock_t pde_unload_lock; /* proc_fops checks and pde_users bumps */
        u8 namelen;
        char name[];
-};
+} __randomize_layout;
 
 union proc_op {
        int (*proc_get_link)(struct dentry *, struct path *);
@@ -70,7 +70,7 @@ struct proc_inode {
        struct hlist_node sysctl_inodes;
        const struct proc_ns_operations *ns_ops;
        struct inode vfs_inode;
-};
+} __randomize_layout;
 
 /*
  * General functions
@@ -279,7 +279,7 @@ struct proc_maps_private {
 #ifdef CONFIG_NUMA
        struct mempolicy *task_mempolicy;
 #endif
-};
+} __randomize_layout;
 
 struct mm_struct *proc_mem_open(struct inode *inode, unsigned int mode);
 
index 05488da3aee9db28e3a233564421efe6971a2a32..3ae9013eeaaa4367bb160aef88b36ab549b0446d 100644 (file)
@@ -46,7 +46,7 @@ struct linux_binprm {
        unsigned interp_flags;
        unsigned interp_data;
        unsigned long loader, exec;
-};
+} __randomize_layout;
 
 #define BINPRM_FLAGS_ENFORCE_NONDUMP_BIT 0
 #define BINPRM_FLAGS_ENFORCE_NONDUMP (1 << BINPRM_FLAGS_ENFORCE_NONDUMP_BIT)
@@ -81,7 +81,7 @@ struct linux_binfmt {
        int (*load_shlib)(struct file *);
        int (*core_dump)(struct coredump_params *cprm);
        unsigned long min_coredump;     /* minimal dump size */
-};
+} __randomize_layout;
 
 extern void __register_binfmt(struct linux_binfmt *fmt, int insert);
 
index 408bc09ce497bb14fdd058b11debbdda7c22fa78..cb28eb21e3ca52054fbb65d72e22c93127aaf472 100644 (file)
@@ -17,7 +17,7 @@ struct cdev {
        struct list_head list;
        dev_t dev;
        unsigned int count;
-};
+} __randomize_layout;
 
 void cdev_init(struct cdev *, const struct file_operations *);
 
index f0f6c537b64cbc37bfba285b3373ee085ef806e2..040dd105c3e72aa4d9e20621515381192ab2b07f 100644 (file)
 #define CEPH_FEATURE_INCARNATION_2 (1ull<<57) // CEPH_FEATURE_SERVER_JEWEL
 
 #define DEFINE_CEPH_FEATURE(bit, incarnation, name)                    \
-       const static uint64_t CEPH_FEATURE_##name = (1ULL<<bit);                \
-       const static uint64_t CEPH_FEATUREMASK_##name =                 \
+       static const uint64_t CEPH_FEATURE_##name = (1ULL<<bit);                \
+       static const uint64_t CEPH_FEATUREMASK_##name =                 \
                (1ULL<<bit | CEPH_FEATURE_INCARNATION_##incarnation);
 
 /* this bit is ignored but still advertised by release *when* */
 #define DEFINE_CEPH_FEATURE_DEPRECATED(bit, incarnation, name, when) \
-       const static uint64_t DEPRECATED_CEPH_FEATURE_##name = (1ULL<<bit); \
-       const static uint64_t DEPRECATED_CEPH_FEATUREMASK_##name =              \
+       static const uint64_t DEPRECATED_CEPH_FEATURE_##name = (1ULL<<bit); \
+       static const uint64_t DEPRECATED_CEPH_FEATUREMASK_##name =              \
                (1ULL<<bit | CEPH_FEATURE_INCARNATION_##incarnation);
 
 /*
index cd4bbe8242bd89802c0440329615c6c64fedbd69..bdb80c4aef6e13631075b2ad06b39d2788c8eba5 100644 (file)
 #endif /* GCC_VERSION >= 40500 */
 
 #if GCC_VERSION >= 40600
+
 /*
  * When used with Link Time Optimization, gcc can optimize away C functions or
  * variables which are referenced only from assembly code.  __visible tells the
  * this.
  */
 #define __visible      __attribute__((externally_visible))
-#endif
+
+/*
+ * RANDSTRUCT_PLUGIN wants to use an anonymous struct, but it is only
+ * possible since GCC 4.6. To provide as much build testing coverage
+ * as possible, this is used for all GCC 4.6+ builds, and not just on
+ * RANDSTRUCT_PLUGIN builds.
+ */
+#define randomized_struct_fields_start struct {
+#define randomized_struct_fields_end   } __randomize_layout;
+
+#endif /* GCC_VERSION >= 40600 */
 
 
 #if GCC_VERSION >= 40900 && !defined(__CHECKER__)
index 219f82f3ec1a731c251b68e40623c01e3152f7eb..eca8ad75e28b054db4657d5e562b3904120b042e 100644 (file)
@@ -452,6 +452,11 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s
 # define __no_randomize_layout
 #endif
 
+#ifndef randomized_struct_fields_start
+# define randomized_struct_fields_start
+# define randomized_struct_fields_end
+#endif
+
 /*
  * Tell gcc if a function is cold. The compiler will assume any path
  * directly leading to the call is unlikely.
index c728d515e5e2fb66ea7a3cc4a3ff93ae9e978b2e..099058e1178b4d8529438450e28ad03b06497d32 100644 (file)
@@ -31,7 +31,7 @@ struct group_info {
        atomic_t        usage;
        int             ngroups;
        kgid_t          gid[0];
-};
+} __randomize_layout;
 
 /**
  * get_group_info - Get a reference to a group info structure
@@ -145,7 +145,7 @@ struct cred {
        struct user_namespace *user_ns; /* user_ns the caps and keyrings are relative to. */
        struct group_info *group_info;  /* supplementary groups for euid/fsgid */
        struct rcu_head rcu;            /* RCU deletion hook */
-};
+} __randomize_layout;
 
 extern void __put_cred(struct cred *);
 extern void exit_creds(struct task_struct *);
index 3f3ff4ccdc3fdc37c87ac345e2c49037ab3294e3..aae1cdb76851308dd825e1558cf007a3722dad73 100644 (file)
@@ -118,7 +118,7 @@ struct dentry {
                struct hlist_bl_node d_in_lookup_hash;  /* only for in-lookup ones */
                struct rcu_head d_rcu;
        } d_u;
-};
+} __randomize_layout;
 
 /*
  * dentry->d_lock spinlock nesting subclasses:
index 7b5d6816542b7f5af171d5680961aeb03184707b..6e1fd5d2124877c16bbbfab4487a772c8f7e37ee 100644 (file)
@@ -296,7 +296,7 @@ struct kiocb {
        void                    *private;
        int                     ki_flags;
        enum rw_hint            ki_hint;
-};
+} __randomize_layout;
 
 static inline bool is_sync_kiocb(struct kiocb *kiocb)
 {
@@ -404,7 +404,7 @@ struct address_space {
        struct list_head        private_list;   /* ditto */
        void                    *private_data;  /* ditto */
        errseq_t                wb_err;
-} __attribute__((aligned(sizeof(long))));
+} __attribute__((aligned(sizeof(long)))) __randomize_layout;
        /*
         * On most architectures that alignment is already the case; but
         * must be enforced here for CRIS, to let the least significant bit
@@ -447,7 +447,7 @@ struct block_device {
        int                     bd_fsfreeze_count;
        /* Mutex for freeze */
        struct mutex            bd_fsfreeze_mutex;
-};
+} __randomize_layout;
 
 /*
  * Radix-tree tags, for tagging dirty and writeback pages within the pagecache
@@ -666,7 +666,7 @@ struct inode {
 #endif
 
        void                    *i_private; /* fs or device private pointer */
-};
+} __randomize_layout;
 
 static inline unsigned int i_blocksize(const struct inode *node)
 {
@@ -883,7 +883,8 @@ struct file {
 #endif /* #ifdef CONFIG_EPOLL */
        struct address_space    *f_mapping;
        errseq_t                f_wb_err;
-} __attribute__((aligned(4))); /* lest something weird decides that 2 is OK */
+} __randomize_layout
+  __attribute__((aligned(4))); /* lest something weird decides that 2 is OK */
 
 struct file_handle {
        __u32 handle_bytes;
@@ -1020,7 +1021,7 @@ struct file_lock {
                        int state;              /* state of grant or error if -ve */
                } afs;
        } fl_u;
-};
+} __randomize_layout;
 
 struct file_lock_context {
        spinlock_t              flc_lock;
@@ -1412,7 +1413,7 @@ struct super_block {
 
        spinlock_t              s_inode_wblist_lock;
        struct list_head        s_inodes_wb;    /* writeback inodes */
-};
+} __randomize_layout;
 
 /* Helper functions so that in most cases filesystems will
  * not need to deal directly with kuid_t and kgid_t and can
@@ -1698,7 +1699,7 @@ struct file_operations {
                        u64);
        ssize_t (*dedupe_file_range)(struct file *, u64, u64, struct file *,
                        u64);
-};
+} __randomize_layout;
 
 struct inode_operations {
        struct dentry * (*lookup) (struct inode *,struct dentry *, unsigned int);
index 0efc3e62843ae74592128dc7e34bd11fbaca4a3c..7a026240cbb1bc0b45f65ac9b14a1f1823501c06 100644 (file)
@@ -12,7 +12,7 @@ struct fs_struct {
        int umask;
        int in_exec;
        struct path root, pwd;
-};
+} __randomize_layout;
 
 extern struct kmem_cache *fs_cachep;
 
index 5591f055e13fd0777da082846331b6d106e3a33d..fadd579d577dc8aafd7c100ea51fe2bf630c76a0 100644 (file)
@@ -23,6 +23,6 @@ struct kern_ipc_perm {
 
        struct rcu_head rcu;
        atomic_t refcount;
-} ____cacheline_aligned_in_smp;
+} ____cacheline_aligned_in_smp __randomize_layout;
 
 #endif /* _LINUX_IPC_H */
index 848e5796400e797a57fb0ab253c6accc215ed9d4..65327ee0936b314fe38fffee3ffb5f882d8883ac 100644 (file)
@@ -61,7 +61,7 @@ struct ipc_namespace {
        struct ucounts *ucounts;
 
        struct ns_common ns;
-};
+} __randomize_layout;
 
 extern struct ipc_namespace init_ipc_ns;
 extern spinlock_t mq_lock;
index 8496cf64575c679b49a0eeedf0c0d3c4d1e2dd1c..9520fc3c3b9ab376ae571cb9895d0dc838212ffc 100644 (file)
@@ -45,7 +45,7 @@ struct key_preparsed_payload {
        size_t          datalen;        /* Raw datalen */
        size_t          quotalen;       /* Quota length for proposed payload */
        time_t          expiry;         /* Expiry time of key */
-};
+} __randomize_layout;
 
 typedef int (*request_key_actor_t)(struct key_construction *key,
                                   const char *op, void *aux);
@@ -158,7 +158,7 @@ struct key_type {
        /* internal fields */
        struct list_head        link;           /* link in types list */
        struct lock_class_key   lock_class;     /* key->sem lock class */
-};
+} __randomize_layout;
 
 extern struct key_type key_type_keyring;
 
index c4e441e00db57c85103e93ffedd16674762df5af..655082c88fd93b5057fc641d196aae66d805850b 100644 (file)
@@ -64,7 +64,7 @@ struct subprocess_info {
        int (*init)(struct subprocess_info *info, struct cred *new);
        void (*cleanup)(struct subprocess_info *info);
        void *data;
-};
+} __randomize_layout;
 
 extern int
 call_usermodehelper(const char *path, char **argv, char **envp, int wait);
index eeab34b0f58912bbcf92607f90cf022414378410..4d800c79475a29fca0cf87c6936174c4ffd509d2 100644 (file)
@@ -172,7 +172,7 @@ struct kset {
        spinlock_t list_lock;
        struct kobject kobj;
        const struct kset_uevent_ops *uevent_ops;
-};
+} __randomize_layout;
 
 extern void kset_init(struct kset *kset);
 extern int __must_check kset_register(struct kset *kset);
index d11738110a7aeff53b1349f994e3e435d2f0e76b..1957635e6d5f7b677896c50921627aff79445cfb 100644 (file)
@@ -92,6 +92,23 @@ static inline void init_llist_head(struct llist_head *list)
 #define llist_entry(ptr, type, member)         \
        container_of(ptr, type, member)
 
+/**
+ * member_address_is_nonnull - check whether the member address is not NULL
+ * @ptr:       the object pointer (struct type * that contains the llist_node)
+ * @member:    the name of the llist_node within the struct.
+ *
+ * This macro is conceptually the same as
+ *     &ptr->member != NULL
+ * but it works around the fact that compilers can decide that taking a member
+ * address is never a NULL pointer.
+ *
+ * Real objects that start at a high address and have a member at NULL are
+ * unlikely to exist, but such pointers may be returned e.g. by the
+ * container_of() macro.
+ */
+#define member_address_is_nonnull(ptr, member) \
+       ((uintptr_t)(ptr) + offsetof(typeof(*(ptr)), member) != 0)
+
 /**
  * llist_for_each - iterate over some deleted entries of a lock-less list
  * @pos:       the &struct llist_node to use as a loop cursor
@@ -145,7 +162,7 @@ static inline void init_llist_head(struct llist_head *list)
  */
 #define llist_for_each_entry(pos, node, member)                                \
        for ((pos) = llist_entry((node), typeof(*(pos)), member);       \
-            &(pos)->member != NULL;                                    \
+            member_address_is_nonnull(pos, member);                    \
             (pos) = llist_entry((pos)->member.next, typeof(*(pos)), member))
 
 /**
@@ -167,7 +184,7 @@ static inline void init_llist_head(struct llist_head *list)
  */
 #define llist_for_each_entry_safe(pos, n, node, member)                               \
        for (pos = llist_entry((node), typeof(*pos), member);                  \
-            &pos->member != NULL &&                                           \
+            member_address_is_nonnull(pos, member) &&                         \
                (n = llist_entry(pos->member.next, typeof(*n), member), true); \
             pos = n)
 
index 7a86925ba8f30033ef2402d7a34b76c1498fe2bf..3a90febadbe20e6756819dcd04e235a05fb7d99e 100644 (file)
@@ -1912,7 +1912,7 @@ struct security_hook_heads {
        struct list_head audit_rule_match;
        struct list_head audit_rule_free;
 #endif /* CONFIG_AUDIT */
-};
+} __randomize_layout;
 
 /*
  * Security module hook list structure.
@@ -1923,7 +1923,7 @@ struct security_hook_list {
        struct list_head                *head;
        union security_list_options     hook;
        char                            *lsm;
-};
+} __randomize_layout;
 
 /*
  * Initializing a security_hook_list structure takes
index d5bed0875d309ce95025dbcab502f51815ca431b..aad5d81dfb444aeb0dcb4b92aef475023aa897c1 100644 (file)
@@ -1068,7 +1068,7 @@ static inline int mlx4_is_eth(struct mlx4_dev *dev, int port)
 }
 
 int mlx4_buf_alloc(struct mlx4_dev *dev, int size, int max_direct,
-                  struct mlx4_buf *buf, gfp_t gfp);
+                  struct mlx4_buf *buf);
 void mlx4_buf_free(struct mlx4_dev *dev, int size, struct mlx4_buf *buf);
 static inline void *mlx4_buf_offset(struct mlx4_buf *buf, int offset)
 {
@@ -1105,10 +1105,9 @@ int mlx4_mw_enable(struct mlx4_dev *dev, struct mlx4_mw *mw);
 int mlx4_write_mtt(struct mlx4_dev *dev, struct mlx4_mtt *mtt,
                   int start_index, int npages, u64 *page_list);
 int mlx4_buf_write_mtt(struct mlx4_dev *dev, struct mlx4_mtt *mtt,
-                      struct mlx4_buf *buf, gfp_t gfp);
+                      struct mlx4_buf *buf);
 
-int mlx4_db_alloc(struct mlx4_dev *dev, struct mlx4_db *db, int order,
-                 gfp_t gfp);
+int mlx4_db_alloc(struct mlx4_dev *dev, struct mlx4_db *db, int order);
 void mlx4_db_free(struct mlx4_dev *dev, struct mlx4_db *db);
 
 int mlx4_alloc_hwq_res(struct mlx4_dev *dev, struct mlx4_hwq_resources *wqres,
@@ -1124,8 +1123,7 @@ int mlx4_qp_reserve_range(struct mlx4_dev *dev, int cnt, int align,
                          int *base, u8 flags);
 void mlx4_qp_release_range(struct mlx4_dev *dev, int base_qpn, int cnt);
 
-int mlx4_qp_alloc(struct mlx4_dev *dev, int qpn, struct mlx4_qp *qp,
-                 gfp_t gfp);
+int mlx4_qp_alloc(struct mlx4_dev *dev, int qpn, struct mlx4_qp *qp);
 void mlx4_qp_free(struct mlx4_dev *dev, struct mlx4_qp *qp);
 
 int mlx4_srq_alloc(struct mlx4_dev *dev, u32 pdn, u32 cqn, u16 xrcdn,
index 45cdb27791a33ff8d494549ce92f080a93434889..ff151814a02d98b613237d1602839fd18358e115 100644 (file)
@@ -342,7 +342,7 @@ struct vm_area_struct {
        struct mempolicy *vm_policy;    /* NUMA policy for the VMA */
 #endif
        struct vm_userfaultfd_ctx vm_userfaultfd_ctx;
-};
+} __randomize_layout;
 
 struct core_thread {
        struct task_struct *task;
@@ -500,7 +500,7 @@ struct mm_struct {
        atomic_long_t hugetlb_usage;
 #endif
        struct work_struct async_put_work;
-};
+} __randomize_layout;
 
 extern struct mm_struct init_mm;
 
index 8eb9a1e693e5b3ae245e93771b4489d5307b08b6..e7bdd549e527bde19eeb565f8e5735d80f589d92 100644 (file)
@@ -45,7 +45,7 @@ struct module_kobject {
        struct kobject *drivers_dir;
        struct module_param_attrs *mp;
        struct completion *kobj_completion;
-};
+} __randomize_layout;
 
 struct module_attribute {
        struct attribute attr;
@@ -475,7 +475,7 @@ struct module {
        ctor_fn_t *ctors;
        unsigned int num_ctors;
 #endif
-} ____cacheline_aligned;
+} ____cacheline_aligned __randomize_layout;
 #ifndef MODULE_ARCH_INIT
 #define MODULE_ARCH_INIT {}
 #endif
index 8e0352af06b786fb0cccde2022af945772f5091e..1ce85e6fd95f798a2e0f2afbb470515d8b0e40dd 100644 (file)
@@ -67,7 +67,7 @@ struct vfsmount {
        struct dentry *mnt_root;        /* root of the mounted tree */
        struct super_block *mnt_sb;     /* pointer to superblock */
        int mnt_flags;
-};
+} __randomize_layout;
 
 struct file; /* forward dec */
 struct path;
index f3f302f9c1975a67ea1c01a828403950fac8a061..a001305f5a79959a5e4f816320f3c4276e308e12 100644 (file)
@@ -29,7 +29,7 @@ struct msg_queue {
        struct list_head q_messages;
        struct list_head q_receivers;
        struct list_head q_senders;
-};
+} __randomize_layout;
 
 /* Helper routines for sys_msgsnd and sys_msgrcv */
 extern long do_msgsnd(int msqid, long mtype, void __user *mtext,
index d1372186f4315c3de45b3949017026dca2d7f109..cde895cc4af4cd5053f1a0f477f15c6a1240eedc 100644 (file)
@@ -7,7 +7,7 @@ struct vfsmount;
 struct path {
        struct vfsmount *mnt;
        struct dentry *dentry;
-};
+} __randomize_layout;
 
 extern void path_get(const struct path *);
 extern void path_put(const struct path *);
index c2a989dee876360d85f305965e34c1dddc0a9c12..b09136f88cf45c3bd84064a88f441c41da6730b3 100644 (file)
@@ -52,7 +52,7 @@ struct pid_namespace {
        int hide_pid;
        int reboot;     /* group exit code if this pidns was rebooted */
        struct ns_common ns;
-};
+} __randomize_layout;
 
 extern struct pid_namespace init_pid_ns;
 
index 58ab28d81fc2ecd4f78f37a81ac07a56d984f2e5..06844b54dfc17a222dc42ce17d4cde5e0d848a8e 100644 (file)
@@ -21,7 +21,7 @@ struct proc_ns_operations {
        int (*install)(struct nsproxy *nsproxy, struct ns_common *ns);
        struct user_namespace *(*owner)(struct ns_common *ns);
        struct ns_common *(*get_parent)(struct ns_common *ns);
-};
+} __randomize_layout;
 
 extern const struct proc_ns_operations netns_operations;
 extern const struct proc_ns_operations utsns_operations;
index 2ba9ec93423f97e97d0dd5ed99d0ee7fb23038f8..8337e2db0bb2e71473f94c283c5e51639ddd8dc8 100644 (file)
@@ -426,7 +426,7 @@ struct sched_rt_entity {
        /* rq "owned" by this entity/group: */
        struct rt_rq                    *my_q;
 #endif
-};
+} __randomize_layout;
 
 struct sched_dl_entity {
        struct rb_node                  rb_node;
@@ -526,6 +526,13 @@ struct task_struct {
 #endif
        /* -1 unrunnable, 0 runnable, >0 stopped: */
        volatile long                   state;
+
+       /*
+        * This begins the randomizable portion of task_struct. Only
+        * scheduling-critical items should be added above here.
+        */
+       randomized_struct_fields_start
+
        void                            *stack;
        atomic_t                        usage;
        /* Per task flags (PF_*), defined further below: */
@@ -1079,6 +1086,13 @@ struct task_struct {
        /* Used by LSM modules for access restriction: */
        void                            *security;
 #endif
+
+       /*
+        * New fields for task_struct should be added above here, so that
+        * they are included in the randomized portion of task_struct.
+        */
+       randomized_struct_fields_end
+
        /* CPU-specific state of this task: */
        struct thread_struct            thread;
 
index c06d63b3a58389b92483bb6a0f24f427324ac000..2a0dd40b15dbae8c49c6196ee9d13b6146f2df8d 100644 (file)
@@ -222,7 +222,7 @@ struct signal_struct {
        struct mutex cred_guard_mutex;  /* guard against foreign influences on
                                         * credential calculations
                                         * (notably. ptrace) */
-};
+} __randomize_layout;
 
 /*
  * Bits in flags field of signal_struct.
index be5cf2ea14ade9d40e88114ea27a5c876423c8a0..de2deb8676bd6c39c55a439b5df98715915eb9c9 100644 (file)
@@ -41,7 +41,7 @@ struct sem_array {
        unsigned int            use_global_lock;/* >0: global lock required */
 
        struct sem              sems[];
-};
+} __randomize_layout;
 
 #ifdef CONFIG_SYSVIPC
 
index 04e88182962511da30753010075c42f8ab30f086..0fb7061ec54c13d29e36ba5b6f09628f4f2ba676 100644 (file)
@@ -22,7 +22,7 @@ struct shmid_kernel /* private to the kernel */
        /* The task created the shm object.  NULL if the task is dead. */
        struct task_struct      *shm_creator;
        struct list_head        shm_clist;      /* list by creator */
-};
+} __randomize_layout;
 
 /* shm_mode upper byte flags */
 #define        SHM_DEST        01000   /* segment will be destroyed on last detach */
index 3a89b9ff4cdc586a7f657f57ef816a431599aeda..1d4dba490fb6830835bf9a35f5edaf4b14bbe9ce 100644 (file)
@@ -120,7 +120,7 @@ struct ctl_table
        struct ctl_table_poll *poll;
        void *extra1;
        void *extra2;
-};
+} __randomize_layout;
 
 struct ctl_node {
        struct rb_node node;
index 69464c0d8068a5fd3bf44b8f7b36d899213172c0..79c30daf46a92160d7560bcc44acdb785b672631 100644 (file)
@@ -332,7 +332,7 @@ struct tty_struct {
        /* If the tty has a pending do_SAK, queue it here - akpm */
        struct work_struct SAK_work;
        struct tty_port *port;
-};
+} __randomize_layout;
 
 /* Each of a tty's open files has private_data pointing to tty_file_private */
 struct tty_file_private {
index b742b5e47cc209ac60e441cc42fcf8f431239fab..00b2213f6a35564974d5be7ac7ba909c464d3e01 100644 (file)
@@ -291,7 +291,7 @@ struct tty_operations {
        void (*poll_put_char)(struct tty_driver *driver, int line, char ch);
 #endif
        const struct file_operations *proc_fops;
-};
+} __randomize_layout;
 
 struct tty_driver {
        int     magic;          /* magic number for this structure */
@@ -325,7 +325,7 @@ struct tty_driver {
 
        const struct tty_operations *ops;
        struct list_head tty_drivers;
-};
+} __randomize_layout;
 
 extern struct list_head tty_drivers;
 
index 32354b4b4b2ba5ae72034d00c3b1d43fa8c2a15c..b3575ce291483284847ccc7eef5fea679fade38b 100644 (file)
@@ -66,7 +66,7 @@ struct user_namespace {
 #endif
        struct ucounts          *ucounts;
        int ucount_max[UCOUNT_COUNTS];
-};
+} __randomize_layout;
 
 struct ucounts {
        struct hlist_node node;
index 60f0bb83b313af0e5429264bb83296735c8cdf01..da826ed059cfd7de52135a40caafe5589b52d2d6 100644 (file)
@@ -26,7 +26,7 @@ struct uts_namespace {
        struct user_namespace *user_ns;
        struct ucounts *ucounts;
        struct ns_common ns;
-};
+} __randomize_layout;
 extern struct uts_namespace init_uts_ns;
 
 #ifdef CONFIG_UTS_NS
index 678e4d6fa31766d64e93a17bc33a81e5d9b634bf..53b1a2cca42129f69a5e4925421a3f0cb3fb2ca9 100644 (file)
@@ -37,7 +37,7 @@ struct unix_skb_parms {
        u32                     secid;          /* Security ID          */
 #endif
        u32                     consumed;
-};
+} __randomize_layout;
 
 #define UNIXCB(skb)    (*(struct unix_skb_parms *)&((skb)->cb))
 
index afc39e3a3f7c030d7f1d5d3d6ae39b0acd635c9b..9816df225af3b4c29017e6a762315e85b3e2733c 100644 (file)
@@ -156,7 +156,7 @@ struct neighbour {
        struct rcu_head         rcu;
        struct net_device       *dev;
        u8                      primary_key[0];
-};
+} __randomize_layout;
 
 struct neigh_ops {
        int                     family;
index 31a2b51bef2c8f05a68f3d6ff3923d94a77592f8..1c401bd4c2e0b78d77a6e94507a9525be716c6d4 100644 (file)
@@ -148,7 +148,7 @@ struct net {
 #endif
        struct sock             *diag_nlsk;
        atomic_t                fnhe_genid;
-};
+} __randomize_layout;
 
 #include <linux/seq_file_net.h>
 
index f69c8c2782dfba68c6f080902cbf5feb0a40a2f0..7c0632c7e87043ca18fe5d32d7d55792f75ca6e8 100644 (file)
@@ -1128,7 +1128,7 @@ struct proto {
        atomic_t                socks;
 #endif
        int                     (*diag_destroy)(struct sock *sk, int err);
-};
+} __randomize_layout;
 
 int proto_register(struct proto *prot, int alloc_slab);
 void proto_unregister(struct proto *prot);
index 356953d3dbd18c351313b3f5e36e92ae24b58cda..b5732432bb297dbf6067ae34b16c00073cb2949d 100644 (file)
@@ -1056,7 +1056,7 @@ enum ib_qp_create_flags {
        IB_QP_CREATE_MANAGED_RECV               = 1 << 4,
        IB_QP_CREATE_NETIF_QP                   = 1 << 5,
        IB_QP_CREATE_SIGNATURE_EN               = 1 << 6,
-       IB_QP_CREATE_USE_GFP_NOIO               = 1 << 7,
+       /* FREE                                 = 1 << 7, */
        IB_QP_CREATE_SCATTER_FCS                = 1 << 8,
        IB_QP_CREATE_CVLAN_STRIPPING            = 1 << 9,
        /* reserve bits 26-31 for low level drivers' internal use */
@@ -2947,6 +2947,22 @@ static inline int ib_post_srq_recv(struct ib_srq *srq,
 struct ib_qp *ib_create_qp(struct ib_pd *pd,
                           struct ib_qp_init_attr *qp_init_attr);
 
+/**
+ * ib_modify_qp_with_udata - Modifies the attributes for the specified QP.
+ * @qp: The QP to modify.
+ * @attr: On input, specifies the QP attributes to modify.  On output,
+ *   the current values of selected QP attributes are returned.
+ * @attr_mask: A bit-mask used to specify which attributes of the QP
+ *   are being modified.
+ * @udata: pointer to user's input output buffer information
+ *   are being modified.
+ * It returns 0 on success and returns appropriate error code on error.
+ */
+int ib_modify_qp_with_udata(struct ib_qp *qp,
+                           struct ib_qp_attr *attr,
+                           int attr_mask,
+                           struct ib_udata *udata);
+
 /**
  * ib_modify_qp - Modifies the attributes for the specified QP and then
  *   transitions the QP to the given state.
index 4878aaf7bdffd871515bc826470ec77886a1c02c..55af692710539d6555c072a0c2a290aca7bfba42 100644 (file)
@@ -229,8 +229,7 @@ struct rvt_driver_provided {
         * ERR_PTR(err).  The driver is free to return NULL or a valid
         * pointer.
         */
-       void * (*qp_priv_alloc)(struct rvt_dev_info *rdi, struct rvt_qp *qp,
-                               gfp_t gfp);
+       void * (*qp_priv_alloc)(struct rvt_dev_info *rdi, struct rvt_qp *qp);
 
        /*
         * Free the driver's private qp structure.
@@ -319,7 +318,7 @@ struct rvt_driver_provided {
 
        /* Let the driver pick the next queue pair number*/
        int (*alloc_qpn)(struct rvt_dev_info *rdi, struct rvt_qpn_table *qpt,
-                        enum ib_qp_type type, u8 port_num, gfp_t gfp);
+                        enum ib_qp_type type, u8 port_num);
 
        /* Determine if its safe or allowed to modify the qp */
        int (*check_modify_qp)(struct rvt_qp *qp, struct ib_qp_attr *attr,
index 833267bbd80bc62b367699eb9cdc646c20fb264c..6dd5569317393889d2f90814dc7b15a840f7e0eb 100644 (file)
@@ -641,6 +641,7 @@ static int auditd_send_unicast_skb(struct sk_buff *skb)
        ac = rcu_dereference(auditd_conn);
        if (!ac) {
                rcu_read_unlock();
+               kfree_skb(skb);
                rc = -ECONNREFUSED;
                goto err;
        }
index ab860453841dfd244c141f329fa9cdecc1f9e063..eee0331342628f09a02720ffe34aba2f8fb12f31 100644 (file)
@@ -279,7 +279,8 @@ static int bringup_wait_for_ap(unsigned int cpu)
 
        /* Wait for the CPU to reach CPUHP_AP_ONLINE_IDLE */
        wait_for_completion(&st->done);
-       BUG_ON(!cpu_online(cpu));
+       if (WARN_ON_ONCE((!cpu_online(cpu))))
+               return -ECANCELED;
 
        /* Unpark the stopper thread and the hotplug thread of the target cpu */
        stop_machine_unpark(cpu);
index c934689043b2bee840513ff2856e0dae74ed5ca2..16dbe4c938953a70a49faf0a5264af8c19a9491f 100644 (file)
@@ -212,7 +212,7 @@ struct futex_pi_state {
        atomic_t refcount;
 
        union futex_key key;
-};
+} __randomize_layout;
 
 /**
  * struct futex_q - The hashed futex queue entry, one per waiting task
@@ -246,7 +246,7 @@ struct futex_q {
        struct rt_mutex_waiter *rt_waiter;
        union futex_key *requeue_pi_key;
        u32 bitset;
-};
+} __randomize_layout;
 
 static const struct futex_q futex_q_init = {
        /* list gets initialized in queue_me()*/
index 5624b2dd6b5807a0658dd8ce1a9bb3dd62a75209..1d1a5b945ab428008ebaa8b31cd1f2a638f6aa97 100644 (file)
@@ -1090,6 +1090,16 @@ setup_irq_thread(struct irqaction *new, unsigned int irq, bool secondary)
 /*
  * Internal function to register an irqaction - typically used to
  * allocate special interrupts that are part of the architecture.
+ *
+ * Locking rules:
+ *
+ * desc->request_mutex Provides serialization against a concurrent free_irq()
+ *   chip_bus_lock     Provides serialization for slow bus operations
+ *     desc->lock      Provides serialization against hard interrupts
+ *
+ * chip_bus_lock and desc->lock are sufficient for all other management and
+ * interrupt related functions. desc->request_mutex solely serializes
+ * request/free_irq().
  */
 static int
 __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
@@ -1167,20 +1177,35 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
        if (desc->irq_data.chip->flags & IRQCHIP_ONESHOT_SAFE)
                new->flags &= ~IRQF_ONESHOT;
 
+       /*
+        * Protects against a concurrent __free_irq() call which might wait
+        * for synchronize_irq() to complete without holding the optional
+        * chip bus lock and desc->lock.
+        */
        mutex_lock(&desc->request_mutex);
+
+       /*
+        * Acquire bus lock as the irq_request_resources() callback below
+        * might rely on the serialization or the magic power management
+        * functions which are abusing the irq_bus_lock() callback,
+        */
+       chip_bus_lock(desc);
+
+       /* First installed action requests resources. */
        if (!desc->action) {
                ret = irq_request_resources(desc);
                if (ret) {
                        pr_err("Failed to request resources for %s (irq %d) on irqchip %s\n",
                               new->name, irq, desc->irq_data.chip->name);
-                       goto out_mutex;
+                       goto out_bus_unlock;
                }
        }
 
-       chip_bus_lock(desc);
-
        /*
         * The following block of code has to be executed atomically
+        * protected against a concurrent interrupt and any of the other
+        * management calls which are not serialized via
+        * desc->request_mutex or the optional bus lock.
         */
        raw_spin_lock_irqsave(&desc->lock, flags);
        old_ptr = &desc->action;
@@ -1286,10 +1311,8 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
                        ret = __irq_set_trigger(desc,
                                                new->flags & IRQF_TRIGGER_MASK);
 
-                       if (ret) {
-                               irq_release_resources(desc);
+                       if (ret)
                                goto out_unlock;
-                       }
                }
 
                desc->istate &= ~(IRQS_AUTODETECT | IRQS_SPURIOUS_DISABLED | \
@@ -1385,12 +1408,10 @@ mismatch:
 out_unlock:
        raw_spin_unlock_irqrestore(&desc->lock, flags);
 
-       chip_bus_sync_unlock(desc);
-
        if (!desc->action)
                irq_release_resources(desc);
-
-out_mutex:
+out_bus_unlock:
+       chip_bus_sync_unlock(desc);
        mutex_unlock(&desc->request_mutex);
 
 out_thread:
@@ -1472,6 +1493,7 @@ static struct irqaction *__free_irq(unsigned int irq, void *dev_id)
                        WARN(1, "Trying to free already-free IRQ %d\n", irq);
                        raw_spin_unlock_irqrestore(&desc->lock, flags);
                        chip_bus_sync_unlock(desc);
+                       mutex_unlock(&desc->request_mutex);
                        return NULL;
                }
 
@@ -1498,6 +1520,20 @@ static struct irqaction *__free_irq(unsigned int irq, void *dev_id)
 #endif
 
        raw_spin_unlock_irqrestore(&desc->lock, flags);
+       /*
+        * Drop bus_lock here so the changes which were done in the chip
+        * callbacks above are synced out to the irq chips which hang
+        * behind a slow bus (I2C, SPI) before calling synchronize_irq().
+        *
+        * Aside of that the bus_lock can also be taken from the threaded
+        * handler in irq_finalize_oneshot() which results in a deadlock
+        * because synchronize_irq() would wait forever for the thread to
+        * complete, which is blocked on the bus lock.
+        *
+        * The still held desc->request_mutex() protects against a
+        * concurrent request_irq() of this irq so the release of resources
+        * and timing data is properly serialized.
+        */
        chip_bus_sync_unlock(desc);
 
        unregister_handler_proc(irq, action);
@@ -1530,8 +1566,15 @@ static struct irqaction *__free_irq(unsigned int irq, void *dev_id)
                }
        }
 
+       /* Last action releases resources */
        if (!desc->action) {
+               /*
+                * Reaquire bus lock as irq_release_resources() might
+                * require it to deallocate resources over the slow bus.
+                */
+               chip_bus_lock(desc);
                irq_release_resources(desc);
+               chip_bus_sync_unlock(desc);
                irq_remove_timings(desc);
        }
 
index 0c31035bbfee8cd682ccf63b3e00728b6252f545..b7cc615d42efdb2219771c7a83c0acd5fa9ea9f5 100644 (file)
@@ -3203,8 +3203,10 @@ static struct ceph_msg_data *ceph_msg_data_create(enum ceph_msg_data_type type)
                return NULL;
 
        data = kmem_cache_zalloc(ceph_msg_data_cache, GFP_NOFS);
-       if (data)
-               data->type = type;
+       if (!data)
+               return NULL;
+
+       data->type = type;
        INIT_LIST_HEAD(&data->links);
 
        return data;
index 86a9737d8e3ff7f86c0ea12e9d417e084b725816..901bb8221366253efb0baa139aee4fa62e8e71e0 100644 (file)
@@ -5310,7 +5310,10 @@ static int invalidate_authorizer(struct ceph_connection *con)
 
 static void osd_reencode_message(struct ceph_msg *msg)
 {
-       encode_request_finish(msg);
+       int type = le16_to_cpu(msg->hdr.type);
+
+       if (type == CEPH_MSG_OSD_OP)
+               encode_request_finish(msg);
 }
 
 static int osd_sign_message(struct ceph_msg *msg)
index 864789c5974e072698841bf6207e9f044e2b8a78..64ae9f89773a1c44f84858eb7622599a81f25de6 100644 (file)
@@ -338,7 +338,7 @@ static void crush_finalize(struct crush_map *c)
 static struct crush_map *crush_decode(void *pbyval, void *end)
 {
        struct crush_map *c;
-       int err = -EINVAL;
+       int err;
        int i, j;
        void **p = &pbyval;
        void *start = pbyval;
@@ -407,7 +407,6 @@ static struct crush_map *crush_decode(void *pbyval, void *end)
                        size = sizeof(struct crush_bucket_straw2);
                        break;
                default:
-                       err = -EINVAL;
                        goto bad;
                }
                BUG_ON(size == 0);
@@ -439,31 +438,31 @@ static struct crush_map *crush_decode(void *pbyval, void *end)
                        err = crush_decode_uniform_bucket(p, end,
                                  (struct crush_bucket_uniform *)b);
                        if (err < 0)
-                               goto bad;
+                               goto fail;
                        break;
                case CRUSH_BUCKET_LIST:
                        err = crush_decode_list_bucket(p, end,
                               (struct crush_bucket_list *)b);
                        if (err < 0)
-                               goto bad;
+                               goto fail;
                        break;
                case CRUSH_BUCKET_TREE:
                        err = crush_decode_tree_bucket(p, end,
                                (struct crush_bucket_tree *)b);
                        if (err < 0)
-                               goto bad;
+                               goto fail;
                        break;
                case CRUSH_BUCKET_STRAW:
                        err = crush_decode_straw_bucket(p, end,
                                (struct crush_bucket_straw *)b);
                        if (err < 0)
-                               goto bad;
+                               goto fail;
                        break;
                case CRUSH_BUCKET_STRAW2:
                        err = crush_decode_straw2_bucket(p, end,
                                (struct crush_bucket_straw2 *)b);
                        if (err < 0)
-                               goto bad;
+                               goto fail;
                        break;
                }
        }
@@ -474,7 +473,6 @@ static struct crush_map *crush_decode(void *pbyval, void *end)
                u32 yes;
                struct crush_rule *r;
 
-               err = -EINVAL;
                ceph_decode_32_safe(p, end, yes, bad);
                if (!yes) {
                        dout("crush_decode NO rule %d off %x %p to %p\n",
@@ -489,7 +487,6 @@ static struct crush_map *crush_decode(void *pbyval, void *end)
                /* len */
                ceph_decode_32_safe(p, end, yes, bad);
 #if BITS_PER_LONG == 32
-               err = -EINVAL;
                if (yes > (ULONG_MAX - sizeof(*r))
                          / sizeof(struct crush_rule_step))
                        goto bad;
@@ -557,7 +554,7 @@ static struct crush_map *crush_decode(void *pbyval, void *end)
        if (*p != end) {
                err = decode_choose_args(p, end, c);
                if (err)
-                       goto bad;
+                       goto fail;
        }
 
 done:
@@ -567,10 +564,14 @@ done:
 
 badmem:
        err = -ENOMEM;
-bad:
+fail:
        dout("crush_decode fail %d\n", err);
        crush_destroy(c);
        return ERR_PTR(err);
+
+bad:
+       err = -EINVAL;
+       goto fail;
 }
 
 int ceph_pg_compare(const struct ceph_pg *lhs, const struct ceph_pg *rhs)
@@ -1399,7 +1400,7 @@ static struct ceph_pg_mapping *__decode_pg_upmap_items(void **p, void *end,
                return ERR_PTR(-EINVAL);
 
        ceph_decode_need(p, end, 2 * len * sizeof(u32), e_inval);
-       pg = kzalloc(sizeof(*pg) + 2 * len * sizeof(u32), GFP_NOIO);
+       pg = alloc_pg_mapping(2 * len * sizeof(u32));
        if (!pg)
                return ERR_PTR(-ENOMEM);
 
@@ -1544,7 +1545,7 @@ static int osdmap_decode(void **p, void *end, struct ceph_osdmap *map)
        if (struct_v >= 3) {
                /* erasure_code_profiles */
                ceph_decode_skip_map_of_map(p, end, string, string, string,
-                                           bad);
+                                           e_inval);
        }
 
        if (struct_v >= 4) {
@@ -1825,9 +1826,9 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end,
        if (struct_v >= 3) {
                /* new_erasure_code_profiles */
                ceph_decode_skip_map_of_map(p, end, string, string, string,
-                                           bad);
+                                           e_inval);
                /* old_erasure_code_profiles */
-               ceph_decode_skip_set(p, end, string, bad);
+               ceph_decode_skip_set(p, end, string, e_inval);
        }
 
        if (struct_v >= 4) {
index 91bc6214ae578fe6c1f0e29f2a37f34eb7575e45..1c02c65470384aa076e2de6885ecba356eb44342 100644 (file)
@@ -198,7 +198,7 @@ struct request_key_auth {
        void                    *callout_info;
        size_t                  callout_len;
        pid_t                   pid;
-};
+} __randomize_layout;
 
 extern struct key_type key_type_request_key_auth;
 extern struct key *request_key_auth_new(struct key *target,