1. 03 1月, 2020 2 次提交
  2. 04 12月, 2019 1 次提交
  3. 27 11月, 2019 1 次提交
  4. 18 11月, 2019 1 次提交
  5. 13 11月, 2019 3 次提交
    • C
      block: rework zone reporting · d4100351
      Christoph Hellwig 提交于
      Avoid the need to allocate a potentially large array of struct blk_zone
      in the block layer by switching the ->report_zones method interface to
      a callback model. Now the caller simply supplies a callback that is
      executed on each reported zone, and private data for it.
      Signed-off-by: NChristoph Hellwig <hch@lst.de>
      Signed-off-by: NShin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
      Signed-off-by: NDamien Le Moal <damien.lemoal@wdc.com>
      Reviewed-by: NHannes Reinecke <hare@suse.de>
      Reviewed-by: NMike Snitzer <snitzer@redhat.com>
      Signed-off-by: NJens Axboe <axboe@kernel.dk>
      d4100351
    • D
      scsi: sd_zbc: Cleanup sd_zbc_alloc_report_buffer() · 23a50861
      Damien Le Moal 提交于
      There is no need to arbitrarily limit the size of a report zone to the
      number of zones defined by SD_ZBC_REPORT_MAX_ZONES. Rather, simply
      calculate the report buffer size needed for the requested number of
      zones without exceeding the device total number of zones. This buffer
      size limitation to the hardware maximum transfer size and page mapping
      capabilities is kept unchanged. Starting with this initial buffer size,
      the allocation is optimized by iterating over decreasing buffer size
      until the allocation succeeds (each iteration is allowed to fail fast
      using the __GFP_NORETRY flag). This ensures forward progress for zone
      reports and avoids failures of zones revalidation under memory pressure.
      
      While at it, also replace the hard coded 512 B sector size with the
      SECTOR_SIZE macro.
      Reviewed-by: NHannes Reinecke <hare@suse.de>
      Reviewed-by: NChristoph Hellwig <hch@lst.de>
      Acked-by: NMartin K. Petersen <martin.petersen@oracle.com>
      Signed-off-by: NDamien Le Moal <damien.lemoal@wdc.com>
      Signed-off-by: NJens Axboe <axboe@kernel.dk>
      23a50861
    • D
      block: Enhance blk_revalidate_disk_zones() · d9dd7308
      Damien Le Moal 提交于
      For ZBC and ZAC zoned devices, the scsi driver revalidation processing
      implemented by sd_revalidate_disk() includes a call to
      sd_zbc_read_zones() which executes a full disk zone report used to
      check that all zones of the disk are the same size. This processing is
      followed by a call to blk_revalidate_disk_zones(), used to initialize
      the device request queue zone bitmaps (zone type and zone write lock
      bitmaps). To do so, blk_revalidate_disk_zones() also executes a full
      device zone report to obtain zone types. As a result, the entire
      zoned block device revalidation process includes two full device zone
      report.
      
      By moving the zone size checks into blk_revalidate_disk_zones(), this
      process can be optimized to a single full device zone report, leading to
      shorter device scan and revalidation times. This patch implements this
      optimization, reducing the original full device zone report implemented
      in sd_zbc_check_zones() to a single, small, report zones command
      execution to obtain the size of the first zone of the device. Checks
      whether all zones of the device are the same size as the first zone
      size are moved to the generic blk_check_zone() function called from
      blk_revalidate_disk_zones().
      
      This optimization also has the following benefits:
      1) fewer memory allocations in the scsi layer during disk revalidation
         as the potentailly large buffer for zone report execution is not
         needed.
      2) Implement zone checks in a generic manner, reducing the burden on
         device driver which only need to obtain the zone size and check that
         this size is a power of 2 number of LBAs. Any new type of zoned
         block device will benefit from this.
      Signed-off-by: NDamien Le Moal <damien.lemoal@wdc.com>
      Reviewed-by: NChristoph Hellwig <hch@lst.de>
      Reviewed-by: NHannes Reinecke <hare@suse.de>
      Signed-off-by: NJens Axboe <axboe@kernel.dk>
      d9dd7308
  6. 07 11月, 2019 1 次提交
  7. 06 11月, 2019 1 次提交
  8. 06 9月, 2019 1 次提交
  9. 05 8月, 2019 1 次提交
  10. 17 7月, 2019 1 次提交
    • D
      scsi: sd_zbc: Fix compilation warning · 0cdc5858
      Damien Le Moal 提交于
      kbuild test robot gets the following compilation warning using gcc 7.4
      cross compilation for c6x (GCC_VERSION=7.4.0 make.cross ARCH=c6x).
      
         In file included from include/asm-generic/bug.h:18:0,
                          from arch/c6x/include/asm/bug.h:12,
                          from include/linux/bug.h:5,
                          from include/linux/thread_info.h:12,
                          from include/asm-generic/current.h:5,
                          from ./arch/c6x/include/generated/asm/current.h:1,
                          from include/linux/sched.h:12,
                          from include/linux/blkdev.h:5,
                          from drivers//scsi/sd_zbc.c:11:
         drivers//scsi/sd_zbc.c: In function 'sd_zbc_read_zones':
      >> include/linux/kernel.h:62:48: warning: 'zone_blocks' may be used
         uninitialized in this function [-Wmaybe-uninitialized]
          #define __round_mask(x, y) ((__typeof__(x))((y)-1))
                                                         ^
         drivers//scsi/sd_zbc.c:464:6: note: 'zone_blocks' was declared here
           u32 zone_blocks;
               ^~~~~~~~~~~
      
      This is a false-positive report. The variable zone_blocks is always
      initialized in sd_zbc_check_zones() before use. It is not initialized
      only and only if sd_zbc_check_zones() fails.
      
      Avoid this warning by initializing the zone_blocks variable to 0.
      
      Fixes: 5f832a39 ("scsi: sd_zbc: Fix sd_zbc_check_zones() error checks")
      Cc: Stable <stable@vger.kernel.org>
      Signed-off-by: NDamien Le Moal <damien.lemoal@wdc.com>
      Signed-off-by: NMartin K. Petersen <martin.petersen@oracle.com>
      0cdc5858
  11. 12 7月, 2019 2 次提交
    • D
      sd_zbc: Fix report zones buffer allocation · b091ac61
      Damien Le Moal 提交于
      During disk scan and revalidation done with sd_revalidate(), the zones
      of a zoned disk are checked using the helper function
      blk_revalidate_disk_zones() if a configuration change is detected
      (change in the number of zones or zone size). The function
      blk_revalidate_disk_zones() issues report_zones calls that are very
      large, that is, to obtain zone information for all zones of the disk
      with a single command. The size of the report zones command buffer
      necessary for such large request generally is lower than the disk
      max_hw_sectors and KMALLOC_MAX_SIZE (4MB) and succeeds on boot (no
      memory fragmentation), but often fail at run time (e.g. hot-plug
      event). This causes the disk revalidation to fail and the disk
      capacity to be changed to 0.
      
      This problem can be avoided by using vmalloc() instead of kmalloc() for
      the buffer allocation. To limit the amount of memory to be allocated,
      this patch also introduces the arbitrary SD_ZBC_REPORT_MAX_ZONES
      maximum number of zones to report with a single report zones command.
      This limit may be lowered further to satisfy the disk max_hw_sectors
      limit. Finally, to ensure that the vmalloc-ed buffer can always be
      mapped in a request, the buffer size is further limited to at most
      queue_max_segments() pages, allowing successful mapping of the buffer
      even in the worst case scenario where none of the buffer pages are
      contiguous.
      
      Fixes: 515ce606 ("scsi: sd_zbc: Fix sd_zbc_report_zones() buffer allocation")
      Fixes: e76239a3 ("block: add a report_zones method")
      Cc: stable@vger.kernel.org
      Reviewed-by: NChristoph Hellwig <hch@lst.de>
      Reviewed-by: NMartin K. Petersen <martin.petersen@oracle.com>
      Signed-off-by: NDamien Le Moal <damien.lemoal@wdc.com>
      Signed-off-by: NJens Axboe <axboe@kernel.dk>
      b091ac61
    • D
      block: Kill gfp_t argument of blkdev_report_zones() · bd976e52
      Damien Le Moal 提交于
      Only GFP_KERNEL and GFP_NOIO are used with blkdev_report_zones(). In
      preparation of using vmalloc() for large report buffer and zone array
      allocations used by this function, remove its "gfp_t gfp_mask" argument
      and rely on the caller context to use memalloc_noio_save/restore() where
      necessary (block layer zone revalidation and dm-zoned I/O error path).
      Reviewed-by: NChristoph Hellwig <hch@lst.de>
      Reviewed-by: NMartin K. Petersen <martin.petersen@oracle.com>
      Signed-off-by: NDamien Le Moal <damien.lemoal@wdc.com>
      Signed-off-by: NJens Axboe <axboe@kernel.dk>
      bd976e52
  12. 05 6月, 2019 1 次提交
  13. 21 5月, 2019 1 次提交
  14. 16 2月, 2019 1 次提交
    • M
      scsi: sd_zbc: Fix sd_zbc_report_zones() buffer allocation · 515ce606
      Masato Suzuki 提交于
      The function sd_zbc_do_report_zones() issues a REPORT ZONES command with a
      buffer size calculated based on the number of zones requested by the
      caller. This value should however not exceed the capabilities of the
      hardware maximum command size, that is, should not exceed the
      max_hw_sectors limit of the device. This problem leads to failures of
      report zones commands when re-validating disks with some SAS HBAs.
      
      Fix this by limiting a report zone command buffer size to the minimum of
      the device max_hw_sectors and calculated value based on the requested
      number of zones. This does not change the semantic of the report_zones file
      operation as report zones can always return less zone reports than
      requested. Short reports are handled using a loop execution of the
      report_zones file operation in the function blk_report_zones().
      
      [Damien]
      Before patch 'e76239a3 ("block: add a report_zones method")', report
      zones buffer allocation was limited to max_sectors when allocated in
      blk_report_zones(). This however does not consider the actual format of the
      device reply which is interface dependent.  Limiting the allocation based
      on the size of the expected reply format rather than the size of the array
      of generic sturct blkzone passed by blk_report_zones() makes more sense.
      
      Fixes: e76239a3 ("block: add a report_zones method")
      Cc: stable@vger.kernel.org
      Signed-off-by: NMasato Suzuki <masato.suzuki@wdc.com>
      Signed-off-by: NDamien Le Moal <damien.lemoal@wdc.com>
      Signed-off-by: NMartin K. Petersen <martin.petersen@oracle.com>
      515ce606
  15. 05 2月, 2019 1 次提交
    • D
      scsi: sd_zbc: Fix zone information messages · 88fc41c4
      Damien Le Moal 提交于
      Commit bf505456 ("block: Introduce blk_revalidate_disk_zones()")
      inadvertently broke the message output of sd_zbc_print_zones() because the
      zone information initialization of the scsi disk structure was moved to the
      second scan run while sd_zbc_print_zones() is called on the first
      scan. This leads to the following incorrect message to be printed for any
      ZBC or ZAC zoned disks.
      
      "...[sdX] 4294967295 zones of 0 logical blocks + 1 runt zone"
      
      Fix this by initializing sdkp zone size and number of zones early on the
      first scan. This does not impact the execution of
      blk_revalidate_zones(). This functions is still called only once the block
      device capacity is set on the second revalidate run on boot, or if the disk
      zone configuration changed (i.e. the disk changed).
      
      Fixes: bf505456 ("block: Introduce blk_revalidate_disk_zones()")
      Cc: stable@vger.kernel.org
      Signed-off-by: NDamien Le Moal <damien.lemoal@wdc.com>
      Signed-off-by: NMartin K. Petersen <martin.petersen@oracle.com>
      88fc41c4
  16. 10 11月, 2018 1 次提交
  17. 26 10月, 2018 5 次提交
    • D
      block: Introduce blk_revalidate_disk_zones() · bf505456
      Damien Le Moal 提交于
      Drivers exposing zoned block devices have to initialize and maintain
      correctness (i.e. revalidate) of the device zone bitmaps attached to
      the device request queue (seq_zones_bitmap and seq_zones_wlock).
      
      To simplify coding this, introduce a generic helper function
      blk_revalidate_disk_zones() suitable for most (and likely all) cases.
      This new function always update the seq_zones_bitmap and seq_zones_wlock
      bitmaps as well as the queue nr_zones field when called for a disk
      using a request based queue. For a disk using a BIO based queue, only
      the number of zones is updated since these queues do not have
      schedulers and so do not need the zone bitmaps.
      
      With this change, the zone bitmap initialization code in sd_zbc.c can be
      replaced with a call to this function in sd_zbc_read_zones(), which is
      called from the disk revalidate block operation method.
      
      A call to blk_revalidate_disk_zones() is also added to the null_blk
      driver for devices created with the zoned mode enabled.
      
      Finally, to ensure that zoned devices created with dm-linear or
      dm-flakey expose the correct number of zones through sysfs, a call to
      blk_revalidate_disk_zones() is added to dm_table_set_restrictions().
      
      The zone bitmaps allocated and initialized with
      blk_revalidate_disk_zones() are freed automatically from
      __blk_release_queue() using the block internal function
      blk_queue_free_zone_bitmaps().
      Reviewed-by: NHannes Reinecke <hare@suse.com>
      Reviewed-by: NChristoph Hellwig <hch@lst.de>
      Reviewed-by: NMartin K. Petersen <martin.petersen@oracle.com>
      Reviewed-by: NMike Snitzer <snitzer@redhat.com>
      Signed-off-by: NDamien Le Moal <damien.lemoal@wdc.com>
      Signed-off-by: NJens Axboe <axboe@kernel.dk>
      bf505456
    • C
      block: add a report_zones method · e76239a3
      Christoph Hellwig 提交于
      Dispatching a report zones command through the request queue is a major
      pain due to the command reply payload rewriting necessary. Given that
      blkdev_report_zones() is executing everything synchronously, implement
      report zones as a block device file operation instead, allowing major
      simplification of the code in many places.
      
      sd, null-blk, dm-linear and dm-flakey being the only block device
      drivers supporting exposing zoned block devices, these drivers are
      modified to provide the device side implementation of the
      report_zones() block device file operation.
      
      For device mappers, a new report_zones() target type operation is
      defined so that the upper block layer calls blkdev_report_zones() can
      be propagated down to the underlying devices of the dm targets.
      Implementation for this new operation is added to the dm-linear and
      dm-flakey targets.
      Reviewed-by: NHannes Reinecke <hare@suse.com>
      Signed-off-by: NChristoph Hellwig <hch@lst.de>
      [Damien]
      * Changed method block_device argument to gendisk
      * Various bug fixes and improvements
      * Added support for null_blk, dm-linear and dm-flakey.
      Reviewed-by: NMartin K. Petersen <martin.petersen@oracle.com>
      Reviewed-by: NMike Snitzer <snitzer@redhat.com>
      Signed-off-by: NDamien Le Moal <damien.lemoal@wdc.com>
      Signed-off-by: NJens Axboe <axboe@kernel.dk>
      e76239a3
    • D
      scsi: sd_zbc: Fix sd_zbc_check_zones() error checks · 5f832a39
      Damien Le Moal 提交于
      The unsigned 32 bits overflow check for the zone size value is already
      done within sd_zbc_check_zones() with the test:
      
      } else if (logical_to_sectors(sdkp->device, zone_blocks) > UINT_MAX) {
      
      so there is no need to check again for an out of range value in
      sd_zbc_read_zones(). Simplify the code and fix sd_zbc_check_zones()
      error return to -EFBIG instead of -ENODEV if the zone size is too large.
      Change the return type of sd_zbc_check_zones() to an int for the error
      code and return the zone size (zone_blocks) through a u32 pointer to
      avoid overflowing the signed 32 return value.
      Reviewed-by: NHannes Reinecke <hare@suse.com>
      Acked-by: NMartin K. Petersen <martin.petersen@oracle.com>
      Reviewed-by: NChristoph Hellwig <hch@lst.de>
      Signed-off-by: NDamien Le Moal <damien.lemoal@wdc.com>
      Signed-off-by: NJens Axboe <axboe@kernel.dk>
      5f832a39
    • D
      scsi: sd_zbc: Reduce boot device scan and revalidate time · d2e428e4
      Damien Le Moal 提交于
      Handling checks of ZBC device capacity using the max_lba field of the
      REPORT ZONES command reply for disks with rc_basis == 0 can be done
      using the same report zones command reply used to check the "same"
      field.
      
      Avoid executing a report zones command solely to check the disk capacity
      by merging sd_zbc_check_capacity() into sd_zbc_check_zone_size() and
      renaming that function to sd_zbc_check_zones(). This removes a costly
      execution of a full report zones command and so reduces device scan
      duration at boot time as well as the duration of disk revalidate calls.
      
      Furthermore, setting the partial report bit in the REPORT ZONES command
      cdb can significantly reduce this command execution time as the device
      does not have to count and report the total number of zones that could
      be reported assuming a large enough reply buffer. A non-partial zone
      report is necessary only for the first execution of report zones used to
      check the same field value (to ensure that this value applies to all
      zones of the disk). All other calls to sd_zbc_report_zones() can use a
      partial report to reduce execution time.
      
      Using a 14 TB ZBC disk, these simple changes reduce device scan time at
      boot from about 3.5s down to about 900ms. Disk revalidate times are also
      reduced from about 450ms down to 230ms.
      Reviewed-by: NChristoph Hellwig <hch@lst.de>
      Reviewed-by: NHannes Reinecke <hare@suse.com>
      Acked-by: NMartin K. Petersen <martin.petersen@oracle.com>
      Signed-off-by: NDamien Le Moal <damien.lemoal@wdc.com>
      Signed-off-by: NJens Axboe <axboe@kernel.dk>
      d2e428e4
    • D
      scsi: sd_zbc: Rearrange code · 7f9d35d2
      Damien Le Moal 提交于
      Move the urswrz check out of sd_zbc_read_zones() and into
      sd_zbc_read_zoned_characteristics() where that value is obtained (read
      from the disk zoned characteristics VPD page). Since this function now
      does more than simply reading the VPD page, rename it to
      sd_zbc_check_zoned_characteristics().
      Also fix the error message displayed when reading that VPD page fails.
      Reviewed-by: NChristoph Hellwig <hch@lst.de>
      Reviewed-by: NHannes Reinecke <hare@suse.com>
      Acked-by: NMartin K. Petersen <martin.petersen@oracle.com>
      Signed-off-by: NDamien Le Moal <damien.lemoal@wdc.com>
      Signed-off-by: NJens Axboe <axboe@kernel.dk>
      7f9d35d2
  18. 11 7月, 2018 1 次提交
  19. 03 7月, 2018 1 次提交
  20. 13 6月, 2018 1 次提交
    • K
      treewide: kzalloc_node() -> kcalloc_node() · 590b5b7d
      Kees Cook 提交于
      The kzalloc_node() function has a 2-factor argument form, kcalloc_node(). This
      patch replaces cases of:
      
              kzalloc_node(a * b, gfp, node)
      
      with:
              kcalloc_node(a * b, gfp, node)
      
      as well as handling cases of:
      
              kzalloc_node(a * b * c, gfp, node)
      
      with:
      
              kzalloc_node(array3_size(a, b, c), gfp, node)
      
      as it's slightly less ugly than:
      
              kcalloc_node(array_size(a, b), c, gfp, node)
      
      This does, however, attempt to ignore constant size factors like:
      
              kzalloc_node(4 * 1024, gfp, node)
      
      though any constants defined via macros get caught up in the conversion.
      
      Any factors with a sizeof() of "unsigned char", "char", and "u8" were
      dropped, since they're redundant.
      
      The Coccinelle script used for this was:
      
      // Fix redundant parens around sizeof().
      @@
      type TYPE;
      expression THING, E;
      @@
      
      (
        kzalloc_node(
      -	(sizeof(TYPE)) * E
      +	sizeof(TYPE) * E
        , ...)
      |
        kzalloc_node(
      -	(sizeof(THING)) * E
      +	sizeof(THING) * E
        , ...)
      )
      
      // Drop single-byte sizes and redundant parens.
      @@
      expression COUNT;
      typedef u8;
      typedef __u8;
      @@
      
      (
        kzalloc_node(
      -	sizeof(u8) * (COUNT)
      +	COUNT
        , ...)
      |
        kzalloc_node(
      -	sizeof(__u8) * (COUNT)
      +	COUNT
        , ...)
      |
        kzalloc_node(
      -	sizeof(char) * (COUNT)
      +	COUNT
        , ...)
      |
        kzalloc_node(
      -	sizeof(unsigned char) * (COUNT)
      +	COUNT
        , ...)
      |
        kzalloc_node(
      -	sizeof(u8) * COUNT
      +	COUNT
        , ...)
      |
        kzalloc_node(
      -	sizeof(__u8) * COUNT
      +	COUNT
        , ...)
      |
        kzalloc_node(
      -	sizeof(char) * COUNT
      +	COUNT
        , ...)
      |
        kzalloc_node(
      -	sizeof(unsigned char) * COUNT
      +	COUNT
        , ...)
      )
      
      // 2-factor product with sizeof(type/expression) and identifier or constant.
      @@
      type TYPE;
      expression THING;
      identifier COUNT_ID;
      constant COUNT_CONST;
      @@
      
      (
      - kzalloc_node
      + kcalloc_node
        (
      -	sizeof(TYPE) * (COUNT_ID)
      +	COUNT_ID, sizeof(TYPE)
        , ...)
      |
      - kzalloc_node
      + kcalloc_node
        (
      -	sizeof(TYPE) * COUNT_ID
      +	COUNT_ID, sizeof(TYPE)
        , ...)
      |
      - kzalloc_node
      + kcalloc_node
        (
      -	sizeof(TYPE) * (COUNT_CONST)
      +	COUNT_CONST, sizeof(TYPE)
        , ...)
      |
      - kzalloc_node
      + kcalloc_node
        (
      -	sizeof(TYPE) * COUNT_CONST
      +	COUNT_CONST, sizeof(TYPE)
        , ...)
      |
      - kzalloc_node
      + kcalloc_node
        (
      -	sizeof(THING) * (COUNT_ID)
      +	COUNT_ID, sizeof(THING)
        , ...)
      |
      - kzalloc_node
      + kcalloc_node
        (
      -	sizeof(THING) * COUNT_ID
      +	COUNT_ID, sizeof(THING)
        , ...)
      |
      - kzalloc_node
      + kcalloc_node
        (
      -	sizeof(THING) * (COUNT_CONST)
      +	COUNT_CONST, sizeof(THING)
        , ...)
      |
      - kzalloc_node
      + kcalloc_node
        (
      -	sizeof(THING) * COUNT_CONST
      +	COUNT_CONST, sizeof(THING)
        , ...)
      )
      
      // 2-factor product, only identifiers.
      @@
      identifier SIZE, COUNT;
      @@
      
      - kzalloc_node
      + kcalloc_node
        (
      -	SIZE * COUNT
      +	COUNT, SIZE
        , ...)
      
      // 3-factor product with 1 sizeof(type) or sizeof(expression), with
      // redundant parens removed.
      @@
      expression THING;
      identifier STRIDE, COUNT;
      type TYPE;
      @@
      
      (
        kzalloc_node(
      -	sizeof(TYPE) * (COUNT) * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        kzalloc_node(
      -	sizeof(TYPE) * (COUNT) * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        kzalloc_node(
      -	sizeof(TYPE) * COUNT * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        kzalloc_node(
      -	sizeof(TYPE) * COUNT * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        kzalloc_node(
      -	sizeof(THING) * (COUNT) * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      |
        kzalloc_node(
      -	sizeof(THING) * (COUNT) * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      |
        kzalloc_node(
      -	sizeof(THING) * COUNT * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      |
        kzalloc_node(
      -	sizeof(THING) * COUNT * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      )
      
      // 3-factor product with 2 sizeof(variable), with redundant parens removed.
      @@
      expression THING1, THING2;
      identifier COUNT;
      type TYPE1, TYPE2;
      @@
      
      (
        kzalloc_node(
      -	sizeof(TYPE1) * sizeof(TYPE2) * COUNT
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
        , ...)
      |
        kzalloc_node(
      -	sizeof(TYPE1) * sizeof(THING2) * (COUNT)
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
        , ...)
      |
        kzalloc_node(
      -	sizeof(THING1) * sizeof(THING2) * COUNT
      +	array3_size(COUNT, sizeof(THING1), sizeof(THING2))
        , ...)
      |
        kzalloc_node(
      -	sizeof(THING1) * sizeof(THING2) * (COUNT)
      +	array3_size(COUNT, sizeof(THING1), sizeof(THING2))
        , ...)
      |
        kzalloc_node(
      -	sizeof(TYPE1) * sizeof(THING2) * COUNT
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
        , ...)
      |
        kzalloc_node(
      -	sizeof(TYPE1) * sizeof(THING2) * (COUNT)
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
        , ...)
      )
      
      // 3-factor product, only identifiers, with redundant parens removed.
      @@
      identifier STRIDE, SIZE, COUNT;
      @@
      
      (
        kzalloc_node(
      -	(COUNT) * STRIDE * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kzalloc_node(
      -	COUNT * (STRIDE) * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kzalloc_node(
      -	COUNT * STRIDE * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kzalloc_node(
      -	(COUNT) * (STRIDE) * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kzalloc_node(
      -	COUNT * (STRIDE) * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kzalloc_node(
      -	(COUNT) * STRIDE * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kzalloc_node(
      -	(COUNT) * (STRIDE) * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kzalloc_node(
      -	COUNT * STRIDE * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      )
      
      // Any remaining multi-factor products, first at least 3-factor products,
      // when they're not all constants...
      @@
      expression E1, E2, E3;
      constant C1, C2, C3;
      @@
      
      (
        kzalloc_node(C1 * C2 * C3, ...)
      |
        kzalloc_node(
      -	(E1) * E2 * E3
      +	array3_size(E1, E2, E3)
        , ...)
      |
        kzalloc_node(
      -	(E1) * (E2) * E3
      +	array3_size(E1, E2, E3)
        , ...)
      |
        kzalloc_node(
      -	(E1) * (E2) * (E3)
      +	array3_size(E1, E2, E3)
        , ...)
      |
        kzalloc_node(
      -	E1 * E2 * E3
      +	array3_size(E1, E2, E3)
        , ...)
      )
      
      // And then all remaining 2 factors products when they're not all constants,
      // keeping sizeof() as the second factor argument.
      @@
      expression THING, E1, E2;
      type TYPE;
      constant C1, C2, C3;
      @@
      
      (
        kzalloc_node(sizeof(THING) * C2, ...)
      |
        kzalloc_node(sizeof(TYPE) * C2, ...)
      |
        kzalloc_node(C1 * C2 * C3, ...)
      |
        kzalloc_node(C1 * C2, ...)
      |
      - kzalloc_node
      + kcalloc_node
        (
      -	sizeof(TYPE) * (E2)
      +	E2, sizeof(TYPE)
        , ...)
      |
      - kzalloc_node
      + kcalloc_node
        (
      -	sizeof(TYPE) * E2
      +	E2, sizeof(TYPE)
        , ...)
      |
      - kzalloc_node
      + kcalloc_node
        (
      -	sizeof(THING) * (E2)
      +	E2, sizeof(THING)
        , ...)
      |
      - kzalloc_node
      + kcalloc_node
        (
      -	sizeof(THING) * E2
      +	E2, sizeof(THING)
        , ...)
      |
      - kzalloc_node
      + kcalloc_node
        (
      -	(E1) * E2
      +	E1, E2
        , ...)
      |
      - kzalloc_node
      + kcalloc_node
        (
      -	(E1) * (E2)
      +	E1, E2
        , ...)
      |
      - kzalloc_node
      + kcalloc_node
        (
      -	E1 * E2
      +	E1, E2
        , ...)
      )
      Signed-off-by: NKees Cook <keescook@chromium.org>
      590b5b7d
  21. 06 6月, 2018 1 次提交
  22. 19 4月, 2018 2 次提交
    • B
      scsi: sd_zbc: Avoid that resetting a zone fails sporadically · ccce20fc
      Bart Van Assche 提交于
      Since SCSI scanning occurs asynchronously, since sd_revalidate_disk() is
      called from sd_probe_async() and since sd_revalidate_disk() calls
      sd_zbc_read_zones() it can happen that sd_zbc_read_zones() is called
      concurrently with blkdev_report_zones() and/or blkdev_reset_zones().  That can
      cause these functions to fail with -EIO because sd_zbc_read_zones() e.g. sets
      q->nr_zones to zero before restoring it to the actual value, even if no drive
      characteristics have changed.  Avoid that this can happen by making the
      following changes:
      
      - Protect the code that updates zone information with blk_queue_enter()
        and blk_queue_exit().
      - Modify sd_zbc_setup_seq_zones_bitmap() and sd_zbc_setup() such that
        these functions do not modify struct scsi_disk before all zone
        information has been obtained.
      
      Note: since commit 055f6e18 ("block: Make q_usage_counter also track
      legacy requests"; kernel v4.15) the request queue freezing mechanism also
      affects legacy request queues.
      
      Fixes: 89d94756 ("sd: Implement support for ZBC devices")
      Signed-off-by: NBart Van Assche <bart.vanassche@wdc.com>
      Cc: Jens Axboe <axboe@kernel.dk>
      Cc: Damien Le Moal <damien.lemoal@wdc.com>
      Cc: Christoph Hellwig <hch@lst.de>
      Cc: Hannes Reinecke <hare@suse.com>
      Cc: stable@vger.kernel.org # v4.16
      Reviewed-by: NDamien Le Moal <damien.lemoal@wdc.com>
      Signed-off-by: NMartin K. Petersen <martin.petersen@oracle.com>
      ccce20fc
    • B
      scsi: sd_zbc: Let the SCSI core handle ILLEGAL REQUEST / ASC 0x21 · c9765621
      Bart Van Assche 提交于
      scsi_io_completion() translates the sense key ILLEGAL REQUEST / ASC 0x21 into
      ACTION_FAIL. That means that setting cmd->allowed to zero in sd_zbc_complete()
      for this sense code / ASC combination is not necessary. Hence remove the code
      that resets cmd->allowed from sd_zbc_complete().
      Signed-off-by: NBart Van Assche <bart.vanassche@wdc.com>
      Cc: Damien Le Moal <damien.lemoal@wdc.com>
      Cc: Christoph Hellwig <hch@lst.de>
      Cc: Hannes Reinecke <hare@suse.com>
      Reviewed-by: NDamien Le Moal <damien.lemoal@wdc.com>
      Signed-off-by: NMartin K. Petersen <martin.petersen@oracle.com>
      c9765621
  23. 07 3月, 2018 1 次提交
  24. 02 3月, 2018 1 次提交
  25. 09 1月, 2018 2 次提交
  26. 17 10月, 2017 5 次提交