Merge tag 'for-5.5/drivers-post-20191122' of git://git.kernel.dk/linux-block
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 25 Nov 2019 19:18:03 +0000 (11:18 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 25 Nov 2019 19:18:03 +0000 (11:18 -0800)
Pull additional block driver updates from Jens Axboe:
 "Here's another block driver update, done to avoid conflicts with the
  zoned changes coming next.

  This contains:

   - Prepare SCSI sd for zone open/close/finish support

   - Small NVMe pull request
        - hwmon support (Akinobu)
        - add new co-maintainer (Christoph)
        - work-around for a discard issue on non-conformant drives
          (Eduard)

   - Small nbd leak fix"

* tag 'for-5.5/drivers-post-20191122' of git://git.kernel.dk/linux-block:
  nbd: prevent memory leak
  nvme: hwmon: add quirk to avoid changing temperature threshold
  nvme: hwmon: provide temperature min and max values for each sensor
  nvmet: add another maintainer
  nvme: Discard workaround for non-conformant devices
  nvme: Add hardware monitoring support
  scsi: sd_zbc: add zone open, close, and finish support

1  2 
MAINTAINERS
drivers/block/nbd.c
drivers/nvme/host/core.c
drivers/nvme/host/nvme.h
drivers/nvme/host/pci.c

diff --combined MAINTAINERS
@@@ -643,7 -643,7 +643,7 @@@ F: drivers/net/ethernet/alacritech/
  
  FORCEDETH GIGABIT ETHERNET DRIVER
  M:    Rain River <rain.1986.08.12@gmail.com>
 -M:    Zhu Yanjun <yanjun.zhu@oracle.com>
 +M:    Zhu Yanjun <zyjzyj2000@gmail.com>
  L:    netdev@vger.kernel.org
  S:    Maintained
  F:    drivers/net/ethernet/nvidia/*
@@@ -2165,10 -2165,12 +2165,10 @@@ F:   arch/arm64/boot/dts/realtek
  F:    Documentation/devicetree/bindings/arm/realtek.yaml
  
  ARM/RENESAS ARM64 ARCHITECTURE
 -M:    Simon Horman <horms@verge.net.au>
  M:    Geert Uytterhoeven <geert+renesas@glider.be>
  M:    Magnus Damm <magnus.damm@gmail.com>
  L:    linux-renesas-soc@vger.kernel.org
  Q:    http://patchwork.kernel.org/project/linux-renesas-soc/list/
 -T:    git git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas.git next
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-devel.git next
  S:    Supported
  F:    arch/arm64/boot/dts/renesas/
@@@ -2280,10 -2282,12 +2280,10 @@@ S:   Maintaine
  F:    drivers/media/platform/s5p-mfc/
  
  ARM/SHMOBILE ARM ARCHITECTURE
 -M:    Simon Horman <horms@verge.net.au>
  M:    Geert Uytterhoeven <geert+renesas@glider.be>
  M:    Magnus Damm <magnus.damm@gmail.com>
  L:    linux-renesas-soc@vger.kernel.org
  Q:    http://patchwork.kernel.org/project/linux-renesas-soc/list/
 -T:    git git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas.git next
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-devel.git next
  S:    Supported
  F:    arch/arm/boot/dts/emev2*
@@@ -2323,13 -2327,11 +2323,13 @@@ F:   drivers/edac/altera_edac
  
  ARM/SPREADTRUM SoC SUPPORT
  M:    Orson Zhai <orsonzhai@gmail.com>
 -M:    Baolin Wang <baolin.wang@linaro.org>
 +M:    Baolin Wang <baolin.wang7@gmail.com>
  M:    Chunyan Zhang <zhang.lyra@gmail.com>
  S:    Maintained
  F:    arch/arm64/boot/dts/sprd
  N:    sprd
 +N:    sc27xx
 +N:    sc2731
  
  ARM/STI ARCHITECTURE
  M:    Patrice Chotard <patrice.chotard@st.com>
@@@ -3053,7 -3055,6 +3053,7 @@@ M:      Daniel Borkmann <daniel@iogearbox.ne
  R:    Martin KaFai Lau <kafai@fb.com>
  R:    Song Liu <songliubraving@fb.com>
  R:    Yonghong Song <yhs@fb.com>
 +R:    Andrii Nakryiko <andriin@fb.com>
  L:    netdev@vger.kernel.org
  L:    bpf@vger.kernel.org
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf.git
@@@ -3099,7 -3100,7 +3099,7 @@@ S:      Supporte
  F:    arch/arm64/net/
  
  BPF JIT for MIPS (32-BIT AND 64-BIT)
 -M:    Paul Burton <paul.burton@mips.com>
 +M:    Paul Burton <paulburton@kernel.org>
  L:    netdev@vger.kernel.org
  L:    bpf@vger.kernel.org
  S:    Maintained
@@@ -3186,7 -3187,7 +3186,7 @@@ N:      bcm216
  N:    kona
  F:    arch/arm/mach-bcm/
  
 -BROADCOM BCM2835 ARM ARCHITECTURE
 +BROADCOM BCM2711/BCM2835 ARM ARCHITECTURE
  M:    Eric Anholt <eric@anholt.net>
  M:    Stefan Wahren <wahrenst@gmx.net>
  L:    bcm-kernel-feedback-list@broadcom.com
@@@ -3194,7 -3195,6 +3194,7 @@@ L:      linux-rpi-kernel@lists.infradead.or
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
  T:    git git://github.com/anholt/linux
  S:    Maintained
 +N:    bcm2711
  N:    bcm2835
  F:    drivers/staging/vc04_services
  
@@@ -3241,6 -3241,8 +3241,6 @@@ S:      Maintaine
  F:    drivers/usb/gadget/udc/bcm63xx_udc.*
  
  BROADCOM BCM7XXX ARM ARCHITECTURE
 -M:    Brian Norris <computersforpeace@gmail.com>
 -M:    Gregory Fong <gregory.0xf0@gmail.com>
  M:    Florian Fainelli <f.fainelli@gmail.com>
  M:    bcm-kernel-feedback-list@broadcom.com
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@@ -3261,6 -3263,7 +3261,6 @@@ S:      Maintaine
  F:    drivers/cpufreq/bmips-cpufreq.c
  
  BROADCOM BMIPS MIPS ARCHITECTURE
 -M:    Kevin Cernekee <cernekee@gmail.com>
  M:    Florian Fainelli <f.fainelli@gmail.com>
  L:    bcm-kernel-feedback-list@broadcom.com
  L:    linux-mips@vger.kernel.org
@@@ -3737,6 -3740,7 +3737,6 @@@ F:      drivers/crypto/cavium/cpt
  
  CAVIUM THUNDERX2 ARM64 SOC
  M:    Robert Richter <rrichter@cavium.com>
 -M:    Jayachandran C <jnair@caviumnetworks.com>
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
  S:    Maintained
  F:    arch/arm64/boot/dts/cavium/thunder2-99xx*
@@@ -8001,7 -8005,7 +8001,7 @@@ S:      Maintaine
  F:    drivers/usb/atm/ueagle-atm.c
  
  IMGTEC ASCII LCD DRIVER
 -M:    Paul Burton <paul.burton@mips.com>
 +M:    Paul Burton <paulburton@kernel.org>
  S:    Maintained
  F:    Documentation/devicetree/bindings/auxdisplay/img-ascii-lcd.txt
  F:    drivers/auxdisplay/img-ascii-lcd.c
@@@ -8298,14 -8302,11 +8298,14 @@@ F:   drivers/hid/intel-ish-hid
  
  INTEL IOMMU (VT-d)
  M:    David Woodhouse <dwmw2@infradead.org>
 +M:    Lu Baolu <baolu.lu@linux.intel.com>
  L:    iommu@lists.linux-foundation.org
 -T:    git git://git.infradead.org/iommu-2.6.git
 +T:    git git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git
  S:    Supported
 -F:    drivers/iommu/intel-iommu.c
 +F:    drivers/iommu/dmar.c
 +F:    drivers/iommu/intel*.[ch]
  F:    include/linux/intel-iommu.h
 +F:    include/linux/intel-svm.h
  
  INTEL IOP-ADMA DMA DRIVER
  R:    Dan Williams <dan.j.williams@intel.com>
@@@ -8564,13 -8565,12 +8564,13 @@@ F:   include/linux/iova.
  
  IO_URING
  M:    Jens Axboe <axboe@kernel.dk>
 -L:    linux-block@vger.kernel.org
 -L:    linux-fsdevel@vger.kernel.org
 +L:    io-uring@vger.kernel.org
  T:    git git://git.kernel.dk/linux-block
  T:    git git://git.kernel.dk/liburing
  S:    Maintained
  F:    fs/io_uring.c
 +F:    fs/io-wq.c
 +F:    fs/io-wq.h
  F:    include/uapi/linux/io_uring.h
  
  IPMI SUBSYSTEM
@@@ -9126,7 -9126,7 +9126,7 @@@ F:      drivers/auxdisplay/ks0108.
  F:    include/linux/ks0108.h
  
  L3MDEV
 -M:    David Ahern <dsa@cumulusnetworks.com>
 +M:    David Ahern <dsahern@kernel.org>
  L:    netdev@vger.kernel.org
  S:    Maintained
  F:    net/l3mdev
@@@ -9187,7 -9187,6 +9187,7 @@@ M:      Pavel Machek <pavel@ucw.cz
  R:    Dan Murphy <dmurphy@ti.com>
  L:    linux-leds@vger.kernel.org
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/j.anaszewski/linux-leds.git
 +T:    git git://git.kernel.org/pub/scm/linux/kernel/git/pavel/linux-leds.git
  S:    Maintained
  F:    Documentation/devicetree/bindings/leds/
  F:    drivers/leds/
@@@ -10259,7 -10258,7 +10259,7 @@@ MEDIATEK ETHERNET DRIVE
  M:    Felix Fietkau <nbd@openwrt.org>
  M:    John Crispin <john@phrozen.org>
  M:    Sean Wang <sean.wang@mediatek.com>
 -M:    Nelson Chang <nelson.chang@mediatek.com>
 +M:    Mark Lee <Mark-MC.Lee@mediatek.com>
  L:    netdev@vger.kernel.org
  S:    Maintained
  F:    drivers/net/ethernet/mediatek/
@@@ -10522,12 -10521,8 +10522,12 @@@ F: mm/memblock.
  F:    Documentation/core-api/boot-time-mm.rst
  
  MEMORY MANAGEMENT
 +M:    Andrew Morton <akpm@linux-foundation.org>
  L:    linux-mm@kvack.org
  W:    http://www.linux-mm.org
 +T:    quilt https://ozlabs.org/~akpm/mmotm/
 +T:    quilt https://ozlabs.org/~akpm/mmots/
 +T:    git git://github.com/hnaz/linux-mm.git
  S:    Maintained
  F:    include/linux/mm.h
  F:    include/linux/gfp.h
@@@ -10836,7 -10831,7 +10836,7 @@@ F:   drivers/usb/image/microtek.
  
  MIPS
  M:    Ralf Baechle <ralf@linux-mips.org>
 -M:    Paul Burton <paul.burton@mips.com>
 +M:    Paul Burton <paulburton@kernel.org>
  M:    James Hogan <jhogan@kernel.org>
  L:    linux-mips@vger.kernel.org
  W:    http://www.linux-mips.org/
@@@ -10850,7 -10845,7 +10850,7 @@@ F:   arch/mips
  F:    drivers/platform/mips/
  
  MIPS BOSTON DEVELOPMENT BOARD
 -M:    Paul Burton <paul.burton@mips.com>
 +M:    Paul Burton <paulburton@kernel.org>
  L:    linux-mips@vger.kernel.org
  S:    Maintained
  F:    Documentation/devicetree/bindings/clock/img,boston-clock.txt
@@@ -10860,7 -10855,7 +10860,7 @@@ F:   drivers/clk/imgtec/clk-boston.
  F:    include/dt-bindings/clock/boston-clock.h
  
  MIPS GENERIC PLATFORM
 -M:    Paul Burton <paul.burton@mips.com>
 +M:    Paul Burton <paulburton@kernel.org>
  L:    linux-mips@vger.kernel.org
  S:    Supported
  F:    Documentation/devicetree/bindings/power/mti,mips-cpc.txt
@@@ -11415,6 -11410,7 +11415,6 @@@ F:   include/trace/events/tcp.
  NETWORKING [TLS]
  M:    Boris Pismenny <borisp@mellanox.com>
  M:    Aviad Yehezkel <aviadye@mellanox.com>
 -M:    Dave Watson <davejwatson@fb.com>
  M:    John Fastabend <john.fastabend@gmail.com>
  M:    Daniel Borkmann <daniel@iogearbox.net>
  M:    Jakub Kicinski <jakub.kicinski@netronome.com>
@@@ -11551,7 -11547,6 +11551,7 @@@ NSDEP
  M:    Matthias Maennich <maennich@google.com>
  S:    Maintained
  F:    scripts/nsdeps
 +F:    Documentation/core-api/symbol-namespaces.rst
  
  NTB AMD DRIVER
  M:    Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
@@@ -11638,6 -11633,7 +11638,7 @@@ F:   drivers/nvme/target/fcloop.
  NVM EXPRESS TARGET DRIVER
  M:    Christoph Hellwig <hch@lst.de>
  M:    Sagi Grimberg <sagi@grimberg.me>
+ M:    Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com>
  L:    linux-nvme@lists.infradead.org
  T:    git://git.infradead.org/nvme.git
  W:    http://git.infradead.org/nvme.git
@@@ -12319,15 -12315,12 +12320,15 @@@ F:        arch/parisc
  F:    Documentation/parisc/
  F:    drivers/parisc/
  F:    drivers/char/agp/parisc-agp.c
 +F:    drivers/input/misc/hp_sdc_rtc.c
  F:    drivers/input/serio/gscps2.c
 +F:    drivers/input/serio/hp_sdc*
  F:    drivers/parport/parport_gsc.*
  F:    drivers/tty/serial/8250/8250_gsc.c
  F:    drivers/video/fbdev/sti*
  F:    drivers/video/console/sti*
  F:    drivers/video/logo/logo_parisc*
 +F:    include/linux/hp_sdc.h
  
  PARMAN
  M:    Jiri Pirko <jiri@mellanox.com>
@@@ -13912,7 -13905,7 +13913,7 @@@ F:   drivers/mtd/nand/raw/r852.
  
  RISC-V ARCHITECTURE
  M:    Paul Walmsley <paul.walmsley@sifive.com>
 -M:    Palmer Dabbelt <palmer@sifive.com>
 +M:    Palmer Dabbelt <palmer@dabbelt.com>
  M:    Albert Ou <aou@eecs.berkeley.edu>
  L:    linux-riscv@lists.infradead.org
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux.git
@@@ -14789,7 -14782,7 +14790,7 @@@ F:   drivers/media/usb/siano
  F:    drivers/media/mmc/siano/
  
  SIFIVE DRIVERS
 -M:    Palmer Dabbelt <palmer@sifive.com>
 +M:    Palmer Dabbelt <palmer@dabbelt.com>
  M:    Paul Walmsley <paul.walmsley@sifive.com>
  L:    linux-riscv@lists.infradead.org
  T:    git git://github.com/sifive/riscv-linux.git
@@@ -14799,7 -14792,7 +14800,7 @@@ N:   sifiv
  
  SIFIVE FU540 SYSTEM-ON-CHIP
  M:    Paul Walmsley <paul.walmsley@sifive.com>
 -M:    Palmer Dabbelt <palmer@sifive.com>
 +M:    Palmer Dabbelt <palmer@dabbelt.com>
  L:    linux-riscv@lists.infradead.org
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/pjw/sifive.git
  S:    Supported
@@@ -16774,6 -16767,13 +16775,6 @@@ W:  http://www.linux-usb.org/usbne
  S:    Maintained
  F:    drivers/net/usb/dm9601.c
  
 -USB DIAMOND RIO500 DRIVER
 -M:    Cesar Miquel <miquel@df.uba.ar>
 -L:    rio500-users@lists.sourceforge.net
 -W:    http://rio500.sourceforge.net
 -S:    Maintained
 -F:    drivers/usb/misc/rio500*
 -
  USB EHCI DRIVER
  M:    Alan Stern <stern@rowland.harvard.edu>
  L:    linux-usb@vger.kernel.org
@@@ -17216,7 -17216,6 +17217,7 @@@ F:   virt/lib
  
  VIRTIO AND VHOST VSOCK DRIVER
  M:    Stefan Hajnoczi <stefanha@redhat.com>
 +M:    Stefano Garzarella <sgarzare@redhat.com>
  L:    kvm@vger.kernel.org
  L:    virtualization@lists.linux-foundation.org
  L:    netdev@vger.kernel.org
@@@ -17441,7 -17440,7 +17442,7 @@@ F:   include/linux/regulator
  K:    regulator_get_optional
  
  VRF
 -M:    David Ahern <dsa@cumulusnetworks.com>
 +M:    David Ahern <dsahern@kernel.org>
  M:    Shrijeet Mukherjee <shrijeet@gmail.com>
  L:    netdev@vger.kernel.org
  S:    Maintained
@@@ -18042,7 -18041,6 +18043,7 @@@ F:   Documentation/vm/zsmalloc.rs
  ZSWAP COMPRESSED SWAP CACHING
  M:    Seth Jennings <sjenning@redhat.com>
  M:    Dan Streetman <ddstreet@ieee.org>
 +M:    Vitaly Wool <vitaly.wool@konsulko.com>
  L:    linux-mm@kvack.org
  S:    Maintained
  F:    mm/zswap.c
diff --combined drivers/block/nbd.c
@@@ -248,8 -248,8 +248,8 @@@ static void nbd_put(struct nbd_device *
        if (refcount_dec_and_mutex_lock(&nbd->refs,
                                        &nbd_index_mutex)) {
                idr_remove(&nbd_index_idr, nbd->index);
 -              mutex_unlock(&nbd_index_mutex);
                nbd_dev_remove(nbd);
 +              mutex_unlock(&nbd_index_mutex);
        }
  }
  
@@@ -385,16 -385,17 +385,16 @@@ static enum blk_eh_timer_return nbd_xmi
        struct nbd_device *nbd = cmd->nbd;
        struct nbd_config *config;
  
 +      if (!mutex_trylock(&cmd->lock))
 +              return BLK_EH_RESET_TIMER;
 +
        if (!refcount_inc_not_zero(&nbd->config_refs)) {
                cmd->status = BLK_STS_TIMEOUT;
 +              mutex_unlock(&cmd->lock);
                goto done;
        }
        config = nbd->config;
  
 -      if (!mutex_trylock(&cmd->lock)) {
 -              nbd_config_put(nbd);
 -              return BLK_EH_RESET_TIMER;
 -      }
 -
        if (config->num_connections > 1) {
                dev_err_ratelimited(nbd_to_dev(nbd),
                                    "Connection timed out, retrying (%d/%d alive)\n",
@@@ -710,12 -711,6 +710,12 @@@ static struct nbd_cmd *nbd_read_stat(st
                ret = -ENOENT;
                goto out;
        }
 +      if (cmd->status != BLK_STS_OK) {
 +              dev_err(disk_to_dev(nbd->disk), "Command already handled %p\n",
 +                      req);
 +              ret = -ENOENT;
 +              goto out;
 +      }
        if (test_bit(NBD_CMD_REQUEUED, &cmd->flags)) {
                dev_err(disk_to_dev(nbd->disk), "Raced with timeout on req %p\n",
                        req);
@@@ -797,10 -792,7 +797,10 @@@ static bool nbd_clear_req(struct reques
  {
        struct nbd_cmd *cmd = blk_mq_rq_to_pdu(req);
  
 +      mutex_lock(&cmd->lock);
        cmd->status = BLK_STS_IOERR;
 +      mutex_unlock(&cmd->lock);
 +
        blk_mq_complete_request(req);
        return true;
  }
@@@ -980,26 -972,6 +980,26 @@@ static blk_status_t nbd_queue_rq(struc
        return ret;
  }
  
 +static struct socket *nbd_get_socket(struct nbd_device *nbd, unsigned long fd,
 +                                   int *err)
 +{
 +      struct socket *sock;
 +
 +      *err = 0;
 +      sock = sockfd_lookup(fd, err);
 +      if (!sock)
 +              return NULL;
 +
 +      if (sock->ops->shutdown == sock_no_shutdown) {
 +              dev_err(disk_to_dev(nbd->disk), "Unsupported socket: shutdown callout must be supported.\n");
 +              *err = -EINVAL;
 +              sockfd_put(sock);
 +              return NULL;
 +      }
 +
 +      return sock;
 +}
 +
  static int nbd_add_socket(struct nbd_device *nbd, unsigned long arg,
                          bool netlink)
  {
        struct nbd_sock *nsock;
        int err;
  
 -      sock = sockfd_lookup(arg, &err);
 +      sock = nbd_get_socket(nbd, arg, &err);
        if (!sock)
                return err;
  
                sockfd_put(sock);
                return -ENOMEM;
        }
+       config->socks = socks;
        nsock = kzalloc(sizeof(struct nbd_sock), GFP_KERNEL);
        if (!nsock) {
                sockfd_put(sock);
                return -ENOMEM;
        }
  
-       config->socks = socks;
        nsock->fallback_index = -1;
        nsock->dead = false;
        mutex_init(&nsock->tx_lock);
@@@ -1061,7 -1034,7 +1062,7 @@@ static int nbd_reconnect_socket(struct 
        int i;
        int err;
  
 -      sock = sockfd_lookup(arg, &err);
 +      sock = nbd_get_socket(nbd, arg, &err);
        if (!sock)
                return err;
  
diff --combined drivers/nvme/host/core.c
@@@ -116,26 -116,10 +116,26 @@@ static void nvme_queue_scan(struct nvme
        /*
         * Only new queue scan work when admin and IO queues are both alive
         */
 -      if (ctrl->state == NVME_CTRL_LIVE)
 +      if (ctrl->state == NVME_CTRL_LIVE && ctrl->tagset)
                queue_work(nvme_wq, &ctrl->scan_work);
  }
  
 +/*
 + * Use this function to proceed with scheduling reset_work for a controller
 + * that had previously been set to the resetting state. This is intended for
 + * code paths that can't be interrupted by other reset attempts. A hot removal
 + * may prevent this from succeeding.
 + */
 +int nvme_try_sched_reset(struct nvme_ctrl *ctrl)
 +{
 +      if (ctrl->state != NVME_CTRL_RESETTING)
 +              return -EBUSY;
 +      if (!queue_work(nvme_reset_wq, &ctrl->reset_work))
 +              return -EBUSY;
 +      return 0;
 +}
 +EXPORT_SYMBOL_GPL(nvme_try_sched_reset);
 +
  int nvme_reset_ctrl(struct nvme_ctrl *ctrl)
  {
        if (!nvme_change_ctrl_state(ctrl, NVME_CTRL_RESETTING))
@@@ -153,7 -137,8 +153,7 @@@ int nvme_reset_ctrl_sync(struct nvme_ct
        ret = nvme_reset_ctrl(ctrl);
        if (!ret) {
                flush_work(&ctrl->reset_work);
 -              if (ctrl->state != NVME_CTRL_LIVE &&
 -                  ctrl->state != NVME_CTRL_ADMIN_ONLY)
 +              if (ctrl->state != NVME_CTRL_LIVE)
                        ret = -ENETRESET;
        }
  
@@@ -332,6 -317,15 +332,6 @@@ bool nvme_change_ctrl_state(struct nvme
  
        old_state = ctrl->state;
        switch (new_state) {
 -      case NVME_CTRL_ADMIN_ONLY:
 -              switch (old_state) {
 -              case NVME_CTRL_CONNECTING:
 -                      changed = true;
 -                      /* FALLTHRU */
 -              default:
 -                      break;
 -              }
 -              break;
        case NVME_CTRL_LIVE:
                switch (old_state) {
                case NVME_CTRL_NEW:
                switch (old_state) {
                case NVME_CTRL_NEW:
                case NVME_CTRL_LIVE:
 -              case NVME_CTRL_ADMIN_ONLY:
                        changed = true;
                        /* FALLTHRU */
                default:
        case NVME_CTRL_DELETING:
                switch (old_state) {
                case NVME_CTRL_LIVE:
 -              case NVME_CTRL_ADMIN_ONLY:
                case NVME_CTRL_RESETTING:
                case NVME_CTRL_CONNECTING:
                        changed = true;
                break;
        }
  
 -      if (changed)
 +      if (changed) {
                ctrl->state = new_state;
 +              wake_up_all(&ctrl->state_wq);
 +      }
  
        spin_unlock_irqrestore(&ctrl->lock, flags);
        if (changed && ctrl->state == NVME_CTRL_LIVE)
  }
  EXPORT_SYMBOL_GPL(nvme_change_ctrl_state);
  
 +/*
 + * Returns true for sink states that can't ever transition back to live.
 + */
 +static bool nvme_state_terminal(struct nvme_ctrl *ctrl)
 +{
 +      switch (ctrl->state) {
 +      case NVME_CTRL_NEW:
 +      case NVME_CTRL_LIVE:
 +      case NVME_CTRL_RESETTING:
 +      case NVME_CTRL_CONNECTING:
 +              return false;
 +      case NVME_CTRL_DELETING:
 +      case NVME_CTRL_DEAD:
 +              return true;
 +      default:
 +              WARN_ONCE(1, "Unhandled ctrl state:%d", ctrl->state);
 +              return true;
 +      }
 +}
 +
 +/*
 + * Waits for the controller state to be resetting, or returns false if it is
 + * not possible to ever transition to that state.
 + */
 +bool nvme_wait_reset(struct nvme_ctrl *ctrl)
 +{
 +      wait_event(ctrl->state_wq,
 +                 nvme_change_ctrl_state(ctrl, NVME_CTRL_RESETTING) ||
 +                 nvme_state_terminal(ctrl));
 +      return ctrl->state == NVME_CTRL_RESETTING;
 +}
 +EXPORT_SYMBOL_GPL(nvme_wait_reset);
 +
  static void nvme_free_ns_head(struct kref *ref)
  {
        struct nvme_ns_head *head =
@@@ -613,8 -574,14 +613,14 @@@ static blk_status_t nvme_setup_discard(
        struct nvme_dsm_range *range;
        struct bio *bio;
  
-       range = kmalloc_array(segments, sizeof(*range),
-                               GFP_ATOMIC | __GFP_NOWARN);
+       /*
+        * Some devices do not consider the DSM 'Number of Ranges' field when
+        * determining how much data to DMA. Always allocate memory for maximum
+        * number of segments to prevent device reading beyond end of buffer.
+        */
+       static const size_t alloc_size = sizeof(*range) * NVME_DSM_MAX_RANGES;
+       range = kzalloc(alloc_size, GFP_ATOMIC | __GFP_NOWARN);
        if (!range) {
                /*
                 * If we fail allocation our range, fallback to the controller
  
        req->special_vec.bv_page = virt_to_page(range);
        req->special_vec.bv_offset = offset_in_page(range);
-       req->special_vec.bv_len = sizeof(*range) * segments;
+       req->special_vec.bv_len = alloc_size;
        req->rq_flags |= RQF_SPECIAL_PAYLOAD;
  
        return BLK_STS_OK;
@@@ -1347,6 -1314,8 +1353,6 @@@ static void nvme_update_formats(struct 
                if (ns->disk && nvme_revalidate_disk(ns->disk))
                        nvme_set_queue_dying(ns);
        up_read(&ctrl->namespaces_rwsem);
 -
 -      nvme_remove_invalid_namespaces(ctrl, NVME_NSID_ALL);
  }
  
  static void nvme_passthru_end(struct nvme_ctrl *ctrl, u32 effects)
                nvme_unfreeze(ctrl);
                nvme_mpath_unfreeze(ctrl->subsys);
                mutex_unlock(&ctrl->subsys->lock);
 +              nvme_remove_invalid_namespaces(ctrl, NVME_NSID_ALL);
                mutex_unlock(&ctrl->scan_lock);
        }
        if (effects & NVME_CMD_EFFECTS_CCC)
@@@ -2798,6 -2766,9 +2804,9 @@@ int nvme_init_identify(struct nvme_ctr
        ctrl->oncs = le16_to_cpu(id->oncs);
        ctrl->mtfa = le16_to_cpu(id->mtfa);
        ctrl->oaes = le32_to_cpu(id->oaes);
+       ctrl->wctemp = le16_to_cpu(id->wctemp);
+       ctrl->cctemp = le16_to_cpu(id->cctemp);
        atomic_set(&ctrl->abort_limit, id->acl + 1);
        ctrl->vwc = id->vwc;
        if (id->mdts)
        if (ret < 0)
                return ret;
  
+       if (!ctrl->identified)
+               nvme_hwmon_init(ctrl);
        ctrl->identified = true;
  
        return 0;
@@@ -2914,6 -2888,7 +2926,6 @@@ static int nvme_dev_open(struct inode *
  
        switch (ctrl->state) {
        case NVME_CTRL_LIVE:
 -      case NVME_CTRL_ADMIN_ONLY:
                break;
        default:
                return -EWOULDBLOCK;
@@@ -3207,6 -3182,7 +3219,6 @@@ static ssize_t nvme_sysfs_show_state(st
        static const char *const state_name[] = {
                [NVME_CTRL_NEW]         = "new",
                [NVME_CTRL_LIVE]        = "live",
 -              [NVME_CTRL_ADMIN_ONLY]  = "only-admin",
                [NVME_CTRL_RESETTING]   = "resetting",
                [NVME_CTRL_CONNECTING]  = "connecting",
                [NVME_CTRL_DELETING]    = "deleting",
@@@ -3717,10 -3693,11 +3729,10 @@@ static void nvme_scan_work(struct work_
        struct nvme_id_ctrl *id;
        unsigned nn;
  
 -      if (ctrl->state != NVME_CTRL_LIVE)
 +      /* No tagset on a live ctrl means IO queues could not created */
 +      if (ctrl->state != NVME_CTRL_LIVE || !ctrl->tagset)
                return;
  
 -      WARN_ON_ONCE(!ctrl->tagset);
 -
        if (test_and_clear_bit(NVME_AER_NOTICE_NS_CHANGED, &ctrl->events)) {
                dev_info(ctrl->device, "rescanning namespaces.\n");
                nvme_clear_changed_ns_log(ctrl);
@@@ -3881,13 -3858,13 +3893,13 @@@ static void nvme_fw_act_work(struct wor
                if (time_after(jiffies, fw_act_timeout)) {
                        dev_warn(ctrl->device,
                                "Fw activation timeout, reset controller\n");
 -                      nvme_reset_ctrl(ctrl);
 -                      break;
 +                      nvme_try_sched_reset(ctrl);
 +                      return;
                }
                msleep(100);
        }
  
 -      if (ctrl->state != NVME_CTRL_LIVE)
 +      if (!nvme_change_ctrl_state(ctrl, NVME_CTRL_LIVE))
                return;
  
        nvme_start_queues(ctrl);
@@@ -3907,13 -3884,7 +3919,13 @@@ static void nvme_handle_aen_notice(stru
                nvme_queue_scan(ctrl);
                break;
        case NVME_AER_NOTICE_FW_ACT_STARTING:
 -              queue_work(nvme_wq, &ctrl->fw_act_work);
 +              /*
 +               * We are (ab)using the RESETTING state to prevent subsequent
 +               * recovery actions from interfering with the controller's
 +               * firmware activation.
 +               */
 +              if (nvme_change_ctrl_state(ctrl, NVME_CTRL_RESETTING))
 +                      queue_work(nvme_wq, &ctrl->fw_act_work);
                break;
  #ifdef CONFIG_NVME_MULTIPATH
        case NVME_AER_NOTICE_ANA:
@@@ -4036,7 -4007,6 +4048,7 @@@ int nvme_init_ctrl(struct nvme_ctrl *ct
        INIT_WORK(&ctrl->async_event_work, nvme_async_event_work);
        INIT_WORK(&ctrl->fw_act_work, nvme_fw_act_work);
        INIT_WORK(&ctrl->delete_work, nvme_delete_ctrl_work);
 +      init_waitqueue_head(&ctrl->state_wq);
  
        INIT_DELAYED_WORK(&ctrl->ka_work, nvme_keep_alive_work);
        memset(&ctrl->ka_cmd, 0, sizeof(ctrl->ka_cmd));
diff --combined drivers/nvme/host/nvme.h
@@@ -15,7 -15,6 +15,7 @@@
  #include <linux/sed-opal.h>
  #include <linux/fault-inject.h>
  #include <linux/rcupdate.h>
 +#include <linux/wait.h>
  
  #include <trace/events/block.h>
  
@@@ -115,6 -114,11 +115,11 @@@ enum nvme_quirks 
         * Prevent tag overlap between queues
         */
        NVME_QUIRK_SHARED_TAGS                  = (1 << 13),
+       /*
+        * Don't change the value of the temperature threshold feature
+        */
+       NVME_QUIRK_NO_TEMP_THRESH_CHANGE        = (1 << 14),
  };
  
  /*
@@@ -162,6 -166,7 +167,6 @@@ static inline u16 nvme_req_qid(struct r
  enum nvme_ctrl_state {
        NVME_CTRL_NEW,
        NVME_CTRL_LIVE,
 -      NVME_CTRL_ADMIN_ONLY,    /* Only admin queue live */
        NVME_CTRL_RESETTING,
        NVME_CTRL_CONNECTING,
        NVME_CTRL_DELETING,
@@@ -199,7 -204,6 +204,7 @@@ struct nvme_ctrl 
        struct cdev cdev;
        struct work_struct reset_work;
        struct work_struct delete_work;
 +      wait_queue_head_t state_wq;
  
        struct nvme_subsystem *subsys;
        struct list_head subsys_entry;
        u16 kas;
        u8 npss;
        u8 apsta;
+       u16 wctemp;
+       u16 cctemp;
        u32 oaes;
        u32 aen_result;
        u32 ctratt;
@@@ -466,7 -472,6 +473,7 @@@ void nvme_complete_rq(struct request *r
  bool nvme_cancel_request(struct request *req, void *data, bool reserved);
  bool nvme_change_ctrl_state(struct nvme_ctrl *ctrl,
                enum nvme_ctrl_state new_state);
 +bool nvme_wait_reset(struct nvme_ctrl *ctrl);
  int nvme_disable_ctrl(struct nvme_ctrl *ctrl);
  int nvme_enable_ctrl(struct nvme_ctrl *ctrl);
  int nvme_shutdown_ctrl(struct nvme_ctrl *ctrl);
@@@ -517,7 -522,6 +524,7 @@@ int nvme_set_queue_count(struct nvme_ct
  void nvme_stop_keep_alive(struct nvme_ctrl *ctrl);
  int nvme_reset_ctrl(struct nvme_ctrl *ctrl);
  int nvme_reset_ctrl_sync(struct nvme_ctrl *ctrl);
 +int nvme_try_sched_reset(struct nvme_ctrl *ctrl);
  int nvme_delete_ctrl(struct nvme_ctrl *ctrl);
  
  int nvme_get_log(struct nvme_ctrl *ctrl, u32 nsid, u8 log_page, u8 lsp,
@@@ -668,4 -672,10 +675,10 @@@ static inline struct nvme_ns *nvme_get_
        return dev_to_disk(dev)->private_data;
  }
  
+ #ifdef CONFIG_NVME_HWMON
+ void nvme_hwmon_init(struct nvme_ctrl *ctrl);
+ #else
+ static inline void nvme_hwmon_init(struct nvme_ctrl *ctrl) { }
+ #endif
  #endif /* _NVME_H */
diff --combined drivers/nvme/host/pci.c
@@@ -773,8 -773,7 +773,8 @@@ static blk_status_t nvme_setup_prp_simp
                struct bio_vec *bv)
  {
        struct nvme_iod *iod = blk_mq_rq_to_pdu(req);
 -      unsigned int first_prp_len = dev->ctrl.page_size - bv->bv_offset;
 +      unsigned int offset = bv->bv_offset & (dev->ctrl.page_size - 1);
 +      unsigned int first_prp_len = dev->ctrl.page_size - offset;
  
        iod->first_dma = dma_map_bvec(dev->dev, bv, rq_dma_dir(req), 0);
        if (dma_mapping_error(dev->dev, iod->first_dma))
@@@ -2262,7 -2261,10 +2262,7 @@@ static bool __nvme_disable_io_queues(st
        return true;
  }
  
 -/*
 - * return error value only when tagset allocation failed
 - */
 -static int nvme_dev_add(struct nvme_dev *dev)
 +static void nvme_dev_add(struct nvme_dev *dev)
  {
        int ret;
  
                if (ret) {
                        dev_warn(dev->ctrl.device,
                                "IO queues tagset allocation failed %d\n", ret);
 -                      return ret;
 +                      return;
                }
                dev->ctrl.tagset = &dev->tagset;
        } else {
        }
  
        nvme_dbbuf_set(dev);
 -      return 0;
  }
  
  static int nvme_pci_enable(struct nvme_dev *dev)
@@@ -2462,14 -2465,6 +2462,14 @@@ static void nvme_dev_disable(struct nvm
        mutex_unlock(&dev->shutdown_lock);
  }
  
 +static int nvme_disable_prepare_reset(struct nvme_dev *dev, bool shutdown)
 +{
 +      if (!nvme_wait_reset(&dev->ctrl))
 +              return -EBUSY;
 +      nvme_dev_disable(dev, shutdown);
 +      return 0;
 +}
 +
  static int nvme_setup_prp_pools(struct nvme_dev *dev)
  {
        dev->prp_page_pool = dma_pool_create("prp list page", dev->dev,
@@@ -2493,20 -2488,14 +2493,20 @@@ static void nvme_release_prp_pools(stru
        dma_pool_destroy(dev->prp_small_pool);
  }
  
 +static void nvme_free_tagset(struct nvme_dev *dev)
 +{
 +      if (dev->tagset.tags)
 +              blk_mq_free_tag_set(&dev->tagset);
 +      dev->ctrl.tagset = NULL;
 +}
 +
  static void nvme_pci_free_ctrl(struct nvme_ctrl *ctrl)
  {
        struct nvme_dev *dev = to_nvme_dev(ctrl);
  
        nvme_dbbuf_dma_free(dev);
        put_device(dev->dev);
 -      if (dev->tagset.tags)
 -              blk_mq_free_tag_set(&dev->tagset);
 +      nvme_free_tagset(dev);
        if (dev->ctrl.admin_q)
                blk_put_queue(dev->ctrl.admin_q);
        kfree(dev->queues);
  
  static void nvme_remove_dead_ctrl(struct nvme_dev *dev)
  {
 +      /*
 +       * Set state to deleting now to avoid blocking nvme_wait_reset(), which
 +       * may be holding this pci_dev's device lock.
 +       */
 +      nvme_change_ctrl_state(&dev->ctrl, NVME_CTRL_DELETING);
        nvme_get_ctrl(&dev->ctrl);
        nvme_dev_disable(dev, false);
        nvme_kill_queues(&dev->ctrl);
@@@ -2535,6 -2519,7 +2535,6 @@@ static void nvme_reset_work(struct work
                container_of(work, struct nvme_dev, ctrl.reset_work);
        bool was_suspend = !!(dev->ctrl.ctrl_config & NVME_CC_SHN_NORMAL);
        int result;
 -      enum nvme_ctrl_state new_state = NVME_CTRL_LIVE;
  
        if (WARN_ON(dev->ctrl.state != NVME_CTRL_RESETTING)) {
                result = -ENODEV;
                dev_warn(dev->ctrl.device, "IO queues not created\n");
                nvme_kill_queues(&dev->ctrl);
                nvme_remove_namespaces(&dev->ctrl);
 -              new_state = NVME_CTRL_ADMIN_ONLY;
 +              nvme_free_tagset(dev);
        } else {
                nvme_start_queues(&dev->ctrl);
                nvme_wait_freeze(&dev->ctrl);
 -              /* hit this only when allocate tagset fails */
 -              if (nvme_dev_add(dev))
 -                      new_state = NVME_CTRL_ADMIN_ONLY;
 +              nvme_dev_add(dev);
                nvme_unfreeze(&dev->ctrl);
        }
  
         * If only admin queue live, keep it to do further investigation or
         * recovery.
         */
 -      if (!nvme_change_ctrl_state(&dev->ctrl, new_state)) {
 +      if (!nvme_change_ctrl_state(&dev->ctrl, NVME_CTRL_LIVE)) {
                dev_warn(dev->ctrl.device,
 -                      "failed to mark controller state %d\n", new_state);
 +                      "failed to mark controller live state\n");
                result = -ENODEV;
                goto out;
        }
@@@ -2683,7 -2670,7 +2683,7 @@@ static int nvme_pci_reg_write32(struct 
  
  static int nvme_pci_reg_read64(struct nvme_ctrl *ctrl, u32 off, u64 *val)
  {
 -      *val = readq(to_nvme_dev(ctrl)->bar + off);
 +      *val = lo_hi_readq(to_nvme_dev(ctrl)->bar + off);
        return 0;
  }
  
@@@ -2847,28 -2834,19 +2847,28 @@@ static int nvme_probe(struct pci_dev *p
  static void nvme_reset_prepare(struct pci_dev *pdev)
  {
        struct nvme_dev *dev = pci_get_drvdata(pdev);
 -      nvme_dev_disable(dev, false);
 +
 +      /*
 +       * We don't need to check the return value from waiting for the reset
 +       * state as pci_dev device lock is held, making it impossible to race
 +       * with ->remove().
 +       */
 +      nvme_disable_prepare_reset(dev, false);
 +      nvme_sync_queues(&dev->ctrl);
  }
  
  static void nvme_reset_done(struct pci_dev *pdev)
  {
        struct nvme_dev *dev = pci_get_drvdata(pdev);
 -      nvme_reset_ctrl_sync(&dev->ctrl);
 +
 +      if (!nvme_try_sched_reset(&dev->ctrl))
 +              flush_work(&dev->ctrl.reset_work);
  }
  
  static void nvme_shutdown(struct pci_dev *pdev)
  {
        struct nvme_dev *dev = pci_get_drvdata(pdev);
 -      nvme_dev_disable(dev, true);
 +      nvme_disable_prepare_reset(dev, true);
  }
  
  /*
@@@ -2921,7 -2899,7 +2921,7 @@@ static int nvme_resume(struct device *d
  
        if (ndev->last_ps == U32_MAX ||
            nvme_set_power_state(ctrl, ndev->last_ps) != 0)
 -              nvme_reset_ctrl(ctrl);
 +              return nvme_try_sched_reset(&ndev->ctrl);
        return 0;
  }
  
@@@ -2949,14 -2927,17 +2949,14 @@@ static int nvme_suspend(struct device *
         */
        if (pm_suspend_via_firmware() || !ctrl->npss ||
            !pcie_aspm_enabled(pdev) ||
 -          (ndev->ctrl.quirks & NVME_QUIRK_SIMPLE_SUSPEND)) {
 -              nvme_dev_disable(ndev, true);
 -              return 0;
 -      }
 +          (ndev->ctrl.quirks & NVME_QUIRK_SIMPLE_SUSPEND))
 +              return nvme_disable_prepare_reset(ndev, true);
  
        nvme_start_freeze(ctrl);
        nvme_wait_freeze(ctrl);
        nvme_sync_queues(ctrl);
  
 -      if (ctrl->state != NVME_CTRL_LIVE &&
 -          ctrl->state != NVME_CTRL_ADMIN_ONLY)
 +      if (ctrl->state != NVME_CTRL_LIVE)
                goto unfreeze;
  
        ret = nvme_get_power_state(ctrl, &ndev->last_ps);
                 * Clearing npss forces a controller reset on resume. The
                 * correct value will be rediscovered then.
                 */
 -              nvme_dev_disable(ndev, true);
 +              ret = nvme_disable_prepare_reset(ndev, true);
                ctrl->npss = 0;
 -              ret = 0;
        }
  unfreeze:
        nvme_unfreeze(ctrl);
  static int nvme_simple_suspend(struct device *dev)
  {
        struct nvme_dev *ndev = pci_get_drvdata(to_pci_dev(dev));
 -
 -      nvme_dev_disable(ndev, true);
 -      return 0;
 +      return nvme_disable_prepare_reset(ndev, true);
  }
  
  static int nvme_simple_resume(struct device *dev)
        struct pci_dev *pdev = to_pci_dev(dev);
        struct nvme_dev *ndev = pci_get_drvdata(pdev);
  
 -      nvme_reset_ctrl(&ndev->ctrl);
 -      return 0;
 +      return nvme_try_sched_reset(&ndev->ctrl);
  }
  
  static const struct dev_pm_ops nvme_dev_pm_ops = {
@@@ -3080,7 -3065,8 +3080,8 @@@ static const struct pci_device_id nvme_
                                NVME_QUIRK_DEALLOCATE_ZEROES, },
        { PCI_VDEVICE(INTEL, 0xf1a5),   /* Intel 600P/P3100 */
                .driver_data = NVME_QUIRK_NO_DEEPEST_PS |
-                               NVME_QUIRK_MEDIUM_PRIO_SQ },
+                               NVME_QUIRK_MEDIUM_PRIO_SQ |
+                               NVME_QUIRK_NO_TEMP_THRESH_CHANGE },
        { PCI_VDEVICE(INTEL, 0xf1a6),   /* Intel 760p/Pro 7600p */
                .driver_data = NVME_QUIRK_IGNORE_DEV_SUBNQN, },
        { PCI_VDEVICE(INTEL, 0x5845),   /* Qemu emulated controller */