1. 24 2月, 2017 2 次提交
  2. 20 2月, 2017 3 次提交
    • S
      md/raid1: fix a use-after-free bug · af5f42a7
      Shaohua Li 提交于
      Commit fd76863e (RAID1: a new I/O barrier implementation to remove resync
      window) introduces a user-after-free bug.
      Signed-off-by: NShaohua Li <shli@fb.com>
      af5f42a7
    • C
      RAID1: avoid unnecessary spin locks in I/O barrier code · 824e47da
      colyli@suse.de 提交于
      When I run a parallel reading performan testing on a md raid1 device with
      two NVMe SSDs, I observe very bad throughput in supprise: by fio with 64KB
      block size, 40 seq read I/O jobs, 128 iodepth, overall throughput is
      only 2.7GB/s, this is around 50% of the idea performance number.
      
      The perf reports locking contention happens at allow_barrier() and
      wait_barrier() code,
       - 41.41%  fio [kernel.kallsyms]     [k] _raw_spin_lock_irqsave
         - _raw_spin_lock_irqsave
               + 89.92% allow_barrier
               + 9.34% __wake_up
       - 37.30%  fio [kernel.kallsyms]     [k] _raw_spin_lock_irq
         - _raw_spin_lock_irq
               - 100.00% wait_barrier
      
      The reason is, in these I/O barrier related functions,
       - raise_barrier()
       - lower_barrier()
       - wait_barrier()
       - allow_barrier()
      They always hold conf->resync_lock firstly, even there are only regular
      reading I/Os and no resync I/O at all. This is a huge performance penalty.
      
      The solution is a lockless-like algorithm in I/O barrier code, and only
      holding conf->resync_lock when it has to.
      
      The original idea is from Hannes Reinecke, and Neil Brown provides
      comments to improve it. I continue to work on it, and make the patch into
      current form.
      
      In the new simpler raid1 I/O barrier implementation, there are two
      wait barrier functions,
       - wait_barrier()
         Which calls _wait_barrier(), is used for regular write I/O. If there is
         resync I/O happening on the same I/O barrier bucket, or the whole
         array is frozen, task will wait until no barrier on same barrier bucket,
         or the whold array is unfreezed.
       - wait_read_barrier()
         Since regular read I/O won't interfere with resync I/O (read_balance()
         will make sure only uptodate data will be read out), it is unnecessary
         to wait for barrier in regular read I/Os, waiting in only necessary
         when the whole array is frozen.
      
      The operations on conf->nr_pending[idx], conf->nr_waiting[idx], conf->
      barrier[idx] are very carefully designed in raise_barrier(),
      lower_barrier(), _wait_barrier() and wait_read_barrier(), in order to
      avoid unnecessary spin locks in these functions. Once conf->
      nr_pengding[idx] is increased, a resync I/O with same barrier bucket index
      has to wait in raise_barrier(). Then in _wait_barrier() if no barrier
      raised in same barrier bucket index and array is not frozen, the regular
      I/O doesn't need to hold conf->resync_lock, it can just increase
      conf->nr_pending[idx], and return to its caller. wait_read_barrier() is
      very similar to _wait_barrier(), the only difference is it only waits when
      array is frozen. For heavy parallel reading I/Os, the lockless I/O barrier
      code almostly gets rid of all spin lock cost.
      
      This patch significantly improves raid1 reading peroformance. From my
      testing, a raid1 device built by two NVMe SSD, runs fio with 64KB
      blocksize, 40 seq read I/O jobs, 128 iodepth, overall throughput
      increases from 2.7GB/s to 4.6GB/s (+70%).
      
      Changelog
      V4:
      - Change conf->nr_queued[] to atomic_t.
      - Define BARRIER_BUCKETS_NR_BITS by (PAGE_SHIFT - ilog2(sizeof(atomic_t)))
      V3:
      - Add smp_mb__after_atomic() as Shaohua and Neil suggested.
      - Change conf->nr_queued[] from atomic_t to int.
      - Change conf->array_frozen from atomic_t back to int, and use
        READ_ONCE(conf->array_frozen) to check value of conf->array_frozen
        in _wait_barrier() and wait_read_barrier().
      - In _wait_barrier() and wait_read_barrier(), add a call to
        wake_up(&conf->wait_barrier) after atomic_dec(&conf->nr_pending[idx]),
        to fix a deadlock between  _wait_barrier()/wait_read_barrier and
        freeze_array().
      V2:
      - Remove a spin_lock/unlock pair in raid1d().
      - Add more code comments to explain why there is no racy when checking two
        atomic_t variables at same time.
      V1:
      - Original RFC patch for comments.
      Signed-off-by: NColy Li <colyli@suse.de>
      Cc: Shaohua Li <shli@fb.com>
      Cc: Hannes Reinecke <hare@suse.com>
      Cc: Johannes Thumshirn <jthumshirn@suse.de>
      Cc: Guoqing Jiang <gqjiang@suse.com>
      Reviewed-by: NNeil Brown <neilb@suse.de>
      Signed-off-by: NShaohua Li <shli@fb.com>
      824e47da
    • C
      RAID1: a new I/O barrier implementation to remove resync window · fd76863e
      colyli@suse.de 提交于
      'Commit 79ef3a8a ("raid1: Rewrite the implementation of iobarrier.")'
      introduces a sliding resync window for raid1 I/O barrier, this idea limits
      I/O barriers to happen only inside a slidingresync window, for regular
      I/Os out of this resync window they don't need to wait for barrier any
      more. On large raid1 device, it helps a lot to improve parallel writing
      I/O throughput when there are background resync I/Os performing at
      same time.
      
      The idea of sliding resync widow is awesome, but code complexity is a
      challenge. Sliding resync window requires several variables to work
      collectively, this is complexed and very hard to make it work correctly.
      Just grep "Fixes: 79ef3a8a" in kernel git log, there are 8 more patches
      to fix the original resync window patch. This is not the end, any further
      related modification may easily introduce more regreassion.
      
      Therefore I decide to implement a much simpler raid1 I/O barrier, by
      removing resync window code, I believe life will be much easier.
      
      The brief idea of the simpler barrier is,
       - Do not maintain a global unique resync window
       - Use multiple hash buckets to reduce I/O barrier conflicts, regular
         I/O only has to wait for a resync I/O when both them have same barrier
         bucket index, vice versa.
       - I/O barrier can be reduced to an acceptable number if there are enough
         barrier buckets
      
      Here I explain how the barrier buckets are designed,
       - BARRIER_UNIT_SECTOR_SIZE
         The whole LBA address space of a raid1 device is divided into multiple
         barrier units, by the size of BARRIER_UNIT_SECTOR_SIZE.
         Bio requests won't go across border of barrier unit size, that means
         maximum bio size is BARRIER_UNIT_SECTOR_SIZE<<9 (64MB) in bytes.
         For random I/O 64MB is large enough for both read and write requests,
         for sequential I/O considering underlying block layer may merge them
         into larger requests, 64MB is still good enough.
         Neil also points out that for resync operation, "we want the resync to
         move from region to region fairly quickly so that the slowness caused
         by having to synchronize with the resync is averaged out over a fairly
         small time frame". For full speed resync, 64MB should take less then 1
         second. When resync is competing with other I/O, it could take up a few
         minutes. Therefore 64MB size is fairly good range for resync.
      
       - BARRIER_BUCKETS_NR
         There are BARRIER_BUCKETS_NR buckets in total, which is defined by,
              #define BARRIER_BUCKETS_NR_BITS   (PAGE_SHIFT - 2)
              #define BARRIER_BUCKETS_NR        (1<<BARRIER_BUCKETS_NR_BITS)
         this patch makes the bellowed members of struct r1conf from integer
         to array of integers,
              -       int                     nr_pending;
              -       int                     nr_waiting;
              -       int                     nr_queued;
              -       int                     barrier;
              +       int                     *nr_pending;
              +       int                     *nr_waiting;
              +       int                     *nr_queued;
              +       int                     *barrier;
         number of the array elements is defined as BARRIER_BUCKETS_NR. For 4KB
         kernel space page size, (PAGE_SHIFT - 2) indecates there are 1024 I/O
         barrier buckets, and each array of integers occupies single memory page.
         1024 means for a request which is smaller than the I/O barrier unit size
         has ~0.1% chance to wait for resync to pause, which is quite a small
         enough fraction. Also requesting single memory page is more friendly to
         kernel page allocator than larger memory size.
      
       - I/O barrier bucket is indexed by bio start sector
         If multiple I/O requests hit different I/O barrier units, they only need
         to compete I/O barrier with other I/Os which hit the same I/O barrier
         bucket index with each other. The index of a barrier bucket which a
         bio should look for is calculated by sector_to_idx() which is defined
         in raid1.h as an inline function,
              static inline int sector_to_idx(sector_t sector)
              {
                      return hash_long(sector >> BARRIER_UNIT_SECTOR_BITS,
                                      BARRIER_BUCKETS_NR_BITS);
              }
         Here sector_nr is the start sector number of a bio.
      
       - Single bio won't go across boundary of a I/O barrier unit
         If a request goes across boundary of barrier unit, it will be split. A
         bio may be split in raid1_make_request() or raid1_sync_request(), if
         sectors returned by align_to_barrier_unit_end() is smaller than
         original bio size.
      
      Comparing to single sliding resync window,
       - Currently resync I/O grows linearly, therefore regular and resync I/O
         will conflict within a single barrier units. So the I/O behavior is
         similar to single sliding resync window.
       - But a barrier unit bucket is shared by all barrier units with identical
         barrier uinit index, the probability of conflict might be higher
         than single sliding resync window, in condition that writing I/Os
         always hit barrier units which have identical barrier bucket indexs with
         the resync I/Os. This is a very rare condition in real I/O work loads,
         I cannot imagine how it could happen in practice.
       - Therefore we can achieve a good enough low conflict rate with much
         simpler barrier algorithm and implementation.
      
      There are two changes should be noticed,
       - In raid1d(), I change the code to decrease conf->nr_pending[idx] into
         single loop, it looks like this,
              spin_lock_irqsave(&conf->device_lock, flags);
              conf->nr_queued[idx]--;
              spin_unlock_irqrestore(&conf->device_lock, flags);
         This change generates more spin lock operations, but in next patch of
         this patch set, it will be replaced by a single line code,
              atomic_dec(&conf->nr_queueud[idx]);
         So we don't need to worry about spin lock cost here.
       - Mainline raid1 code split original raid1_make_request() into
         raid1_read_request() and raid1_write_request(). If the original bio
         goes across an I/O barrier unit size, this bio will be split before
         calling raid1_read_request() or raid1_write_request(),  this change
         the code logic more simple and clear.
       - In this patch wait_barrier() is moved from raid1_make_request() to
         raid1_write_request(). In raid_read_request(), original wait_barrier()
         is replaced by raid1_read_request().
         The differnece is wait_read_barrier() only waits if array is frozen,
         using different barrier function in different code path makes the code
         more clean and easy to read.
      Changelog
      V4:
      - Add alloc_r1bio() to remove redundant r1bio memory allocation code.
      - Fix many typos in patch comments.
      - Use (PAGE_SHIFT - ilog2(sizeof(int))) to define BARRIER_BUCKETS_NR_BITS.
      V3:
      - Rebase the patch against latest upstream kernel code.
      - Many fixes by review comments from Neil,
        - Back to use pointers to replace arraries in struct r1conf
        - Remove total_barriers from struct r1conf
        - Add more patch comments to explain how/why the values of
          BARRIER_UNIT_SECTOR_SIZE and BARRIER_BUCKETS_NR are decided.
        - Use get_unqueued_pending() to replace get_all_pendings() and
          get_all_queued()
        - Increase bucket number from 512 to 1024
      - Change code comments format by review from Shaohua.
      V2:
      - Use bio_split() to split the orignal bio if it goes across barrier unit
        bounday, to make the code more simple, by suggestion from Shaohua and
        Neil.
      - Use hash_long() to replace original linear hash, to avoid a possible
        confilict between resync I/O and sequential write I/O, by suggestion from
        Shaohua.
      - Add conf->total_barriers to record barrier depth, which is used to
        control number of parallel sync I/O barriers, by suggestion from Shaohua.
      - In V1 patch the bellowed barrier buckets related members in r1conf are
        allocated in memory page. To make the code more simple, V2 patch moves
        the memory space into struct r1conf, like this,
              -       int                     nr_pending;
              -       int                     nr_waiting;
              -       int                     nr_queued;
              -       int                     barrier;
              +       int                     nr_pending[BARRIER_BUCKETS_NR];
              +       int                     nr_waiting[BARRIER_BUCKETS_NR];
              +       int                     nr_queued[BARRIER_BUCKETS_NR];
              +       int                     barrier[BARRIER_BUCKETS_NR];
        This change is by the suggestion from Shaohua.
      - Remove some inrelavent code comments, by suggestion from Guoqing.
      - Add a missing wait_barrier() before jumping to retry_write, in
        raid1_make_write_request().
      V1:
      - Original RFC patch for comments
      Signed-off-by: NColy Li <colyli@suse.de>
      Cc: Johannes Thumshirn <jthumshirn@suse.de>
      Cc: Guoqing Jiang <gqjiang@suse.com>
      Reviewed-by: NNeil Brown <neilb@suse.de>
      Signed-off-by: NShaohua Li <shli@fb.com>
      fd76863e
  3. 17 2月, 2017 1 次提交
  4. 16 2月, 2017 5 次提交
  5. 14 2月, 2017 11 次提交
    • S
      md: disable WRITE SAME if it fails in underlayer disks · 26483819
      Shaohua Li 提交于
      This makes md do the same thing as dm for write same IO failure. Please
      see 7eee4ae2(dm: disable WRITE SAME if it fails) for details why we need
      this.
      
      We did a little bit different than dm. Instead of disabling writesame in
      the first IO error, we disable it till next writesame IO coming after
      the first IO error. This way we don't need to clone a bio.
      
      Also reported here: https://bugzilla.kernel.org/show_bug.cgi?id=118581Suggested-by: NNeilBrown <neilb@suse.com>
      Acked-by: NNeilBrown <neilb@suse.com>
      Signed-off-by: NShaohua Li <shli@fb.com>
      26483819
    • S
      md/raid5-cache: exclude reclaiming stripes in reclaim check · e33fbb9c
      Shaohua Li 提交于
      stripes which are being reclaimed are still accounted into cached
      stripes. The reclaim takes time. r5c_do_reclaim isn't aware of the
      stripes and does unnecessary stripe reclaim. In practice, I saw one
      stripe is reclaimed one time. This will cause bad IO pattern. Fixing
      this by excluding the reclaing stripes in the check.
      
      Cc: Song Liu <songliubraving@fb.com>
      Signed-off-by: NShaohua Li <shli@fb.com>
      e33fbb9c
    • S
      md/raid5-cache: stripe reclaim only counts valid stripes · e8fd52ee
      Shaohua Li 提交于
      When log space is tight, we try to reclaim stripes from log head. There
      are stripes which can't be reclaimed right now if some conditions are
      met. We skip such stripes but accidentally count them, which might cause
      no stripes are claimed. Fixing this by only counting valid stripes.
      
      Cc: Song Liu <songliubraving@fb.com>
      Signed-off-by: NShaohua Li <shli@fb.com>
      e8fd52ee
    • S
      MD: add doc for raid5-cache · 5a6265f9
      Shaohua Li 提交于
      I'm starting document of the raid5-cache feature. Please note this is a
      kernel doc instead of a mdadm manual, so I don't add the details about
      how to use the feature in mdadm side.
      
      Cc: NeilBrown <neilb@suse.com>
      Reviewed-by: NSong Liu <songliubraving@fb.com>
      Signed-off-by: NShaohua Li <shli@fb.com>
      5a6265f9
    • S
      Documentation: move MD related doc into a separate dir · 1601c590
      Shaohua Li 提交于
      Signed-off-by: NShaohua Li <shli@fb.com>
      1601c590
    • N
      md: ensure md devices are freed before module is unloaded. · 9356863c
      NeilBrown 提交于
      Commit: cbd19983 ("md: Fix unfortunate interaction with evms")
      change mddev_put() so that it would not destroy an md device while
      ->ctime was non-zero.
      
      Unfortunately, we didn't make sure to clear ->ctime when unloading
      the module, so it is possible for an md device to remain after
      module unload.  An attempt to open such a device will trigger
      an invalid memory reference in:
        get_gendisk -> kobj_lookup -> exact_lock -> get_disk
      
      when tring to access disk->fops, which was in the module that has
      been removed.
      
      So ensure we clear ->ctime in md_exit(), and explain how that is useful,
      as it isn't immediately obvious when looking at the code.
      
      Fixes: cbd19983 ("md: Fix unfortunate interaction with evms")
      Tested-by: NGuoqing Jiang <gqjiang@suse.com>
      Signed-off-by: NNeilBrown <neilb@suse.com>
      Signed-off-by: NShaohua Li <shli@fb.com>
      9356863c
    • S
      md/r5cache: improve journal device efficiency · 39b99586
      Song Liu 提交于
      It is important to be able to flush all stripes in raid5-cache.
      Therefore, we need reserve some space on the journal device for
      these flushes. If flush operation includes pending writes to the
      stripe, we need to reserve (conf->raid_disk + 1) pages per stripe
      for the flush out. This reduces the efficiency of journal space.
      If we exclude these pending writes from flush operation, we only
      need (conf->max_degraded + 1) pages per stripe.
      
      With this patch, when log space is critical (R5C_LOG_CRITICAL=1),
      pending writes will be excluded from stripe flush out. Therefore,
      we can reduce reserved space for flush out and thus improve journal
      device efficiency.
      Signed-off-by: NSong Liu <songliubraving@fb.com>
      Signed-off-by: NShaohua Li <shli@fb.com>
      39b99586
    • S
      md/r5cache: enable chunk_aligned_read with write back cache · 03b047f4
      Song Liu 提交于
      Chunk aligned read significantly reduces CPU usage of raid456.
      However, it is not safe to fully bypass the write back cache.
      This patch enables chunk aligned read with write back cache.
      
      For chunk aligned read, we track stripes in write back cache at
      a bigger granularity, "big_stripe". Each chunk may contain more
      than one stripe (for example, a 256kB chunk contains 64 4kB-page,
      so this chunk contain 64 stripes). For chunk_aligned_read, these
      stripes are grouped into one big_stripe, so we only need one lookup
      for the whole chunk.
      
      For each big_stripe, struct big_stripe_info tracks how many stripes
      of this big_stripe are in the write back cache. We count how many
      stripes of this big_stripe are in the write back cache. These
      counters are tracked in a radix tree (big_stripe_tree).
      r5c_tree_index() is used to calculate keys for the radix tree.
      
      chunk_aligned_read() calls r5c_big_stripe_cached() to look up
      big_stripe of each chunk in the tree. If this big_stripe is in the
      tree, chunk_aligned_read() aborts. This look up is protected by
      rcu_read_lock().
      
      It is necessary to remember whether a stripe is counted in
      big_stripe_tree. Instead of adding new flag, we reuses existing flags:
      STRIPE_R5C_PARTIAL_STRIPE and STRIPE_R5C_FULL_STRIPE. If either of these
      two flags are set, the stripe is counted in big_stripe_tree. This
      requires moving set_bit(STRIPE_R5C_PARTIAL_STRIPE) to
      r5c_try_caching_write(); and moving clear_bit of
      STRIPE_R5C_PARTIAL_STRIPE and STRIPE_R5C_FULL_STRIPE to
      r5c_finish_stripe_write_out().
      Signed-off-by: NSong Liu <songliubraving@fb.com>
      Reviewed-by: NNeilBrown <neilb@suse.com>
      Signed-off-by: NShaohua Li <shli@fb.com>
      03b047f4
    • S
      EXPORT_SYMBOL radix_tree_replace_slot · 10257d71
      Song Liu 提交于
      It will be used in drivers/md/raid5-cache.c
      Signed-off-by: NSong Liu <songliubraving@fb.com>
      Signed-off-by: NShaohua Li <shli@fb.com>
      10257d71
    • S
      raid5: only dispatch IO from raid5d for harddisk raid · 765d704d
      Shaohua Li 提交于
      We made raid5 stripe handling multi-thread before. It works well for
      SSD. But for harddisk, the multi-threading creates more disk seek, so
      not always improve performance. For several hard disks based raid5,
      multi-threading is required as raid5d becames a bottleneck especially
      for sequential write.
      
      To overcome the disk seek issue, we only dispatch IO from raid5d if the
      array is harddisk based. Other threads can still handle stripes, but
      can't dispatch IO.
      
      Idealy, we should control IO dispatching order according to IO position
      interrnally. Right now we still depend on block layer, which isn't very
      efficient sometimes though.
      
      My setup has 9 harddisks, each disk can do around 180M/s sequential
      write. So in theory, the raid5 can do 180 * 8 = 1440M/s sequential
      write. The test machine uses an ATOM CPU. I measure sequential write
      with large iodepth bandwidth to raid array:
      
      without patch: ~600M/s
      without patch and group_thread_cnt=4: 750M/s
      with patch and group_thread_cnt=4: 950M/s
      with patch, group_thread_cnt=4, skip_copy=1: 1150M/s
      
      We are pretty close to the maximum bandwidth in the large iodepth
      iodepth case. The performance gap of small iodepth sequential write
      between software raid and theory value is still very big though, because
      we don't have an efficient pipeline.
      
      Cc: NeilBrown <neilb@suse.com>
      Cc: Song Liu <songliubraving@fb.com>
      Signed-off-by: NShaohua Li <shli@fb.com>
      765d704d
    • C
      md linear: fix a race between linear_add() and linear_congested() · 03a9e24e
      colyli@suse.de 提交于
      Recently I receive a bug report that on Linux v3.0 based kerenl, hot add
      disk to a md linear device causes kernel crash at linear_congested(). From
      the crash image analysis, I find in linear_congested(), mddev->raid_disks
      contains value N, but conf->disks[] only has N-1 pointers available. Then
      a NULL pointer deference crashes the kernel.
      
      There is a race between linear_add() and linear_congested(), RCU stuffs
      used in these two functions cannot avoid the race. Since Linuv v4.0
      RCU code is replaced by introducing mddev_suspend().  After checking the
      upstream code, it seems linear_congested() is not called in
      generic_make_request() code patch, so mddev_suspend() cannot provent it
      from being called. The possible race still exists.
      
      Here I explain how the race still exists in current code.  For a machine
      has many CPUs, on one CPU, linear_add() is called to add a hard disk to a
      md linear device; at the same time on other CPU, linear_congested() is
      called to detect whether this md linear device is congested before issuing
      an I/O request onto it.
      
      Now I use a possible code execution time sequence to demo how the possible
      race happens,
      
      seq    linear_add()                linear_congested()
       0                                 conf=mddev->private
       1   oldconf=mddev->private
       2   mddev->raid_disks++
       3                              for (i=0; i<mddev->raid_disks;i++)
       4                                bdev_get_queue(conf->disks[i].rdev->bdev)
       5   mddev->private=newconf
      
      In linear_add() mddev->raid_disks is increased in time seq 2, and on
      another CPU in linear_congested() the for-loop iterates conf->disks[i] by
      the increased mddev->raid_disks in time seq 3,4. But conf with one more
      element (which is a pointer to struct dev_info type) to conf->disks[] is
      not updated yet, accessing its structure member in time seq 4 will cause a
      NULL pointer deference fault.
      
      To fix this race, there are 2 parts of modification in the patch,
       1) Add 'int raid_disks' in struct linear_conf, as a copy of
          mddev->raid_disks. It is initialized in linear_conf(), always being
          consistent with pointers number of 'struct dev_info disks[]'. When
          iterating conf->disks[] in linear_congested(), use conf->raid_disks to
          replace mddev->raid_disks in the for-loop, then NULL pointer deference
          will not happen again.
       2) RCU stuffs are back again, and use kfree_rcu() in linear_add() to
          free oldconf memory. Because oldconf may be referenced as mddev->private
          in linear_congested(), kfree_rcu() makes sure that its memory will not
          be released until no one uses it any more.
      Also some code comments are added in this patch, to make this modification
      to be easier understandable.
      
      This patch can be applied for kernels since v4.0 after commit:
      3be260cc ("md/linear: remove rcu protections in favour of
      suspend/resume"). But this bug is reported on Linux v3.0 based kernel, for
      people who maintain kernels before Linux v4.0, they need to do some back
      back port to this patch.
      
      Changelog:
       - V3: add 'int raid_disks' in struct linear_conf, and use kfree_rcu() to
             replace rcu_call() in linear_add().
       - v2: add RCU stuffs by suggestion from Shaohua and Neil.
       - v1: initial effort.
      Signed-off-by: NColy Li <colyli@suse.de>
      Cc: Shaohua Li <shli@fb.com>
      Cc: Neil Brown <neilb@suse.com>
      Cc: stable@vger.kernel.org
      Signed-off-by: NShaohua Li <shli@fb.com>
      03a9e24e
  6. 13 2月, 2017 1 次提交
  7. 12 2月, 2017 7 次提交
  8. 11 2月, 2017 10 次提交
    • O
      Btrfs: fix btrfs_decompress_buf2page() · 6e78b3f7
      Omar Sandoval 提交于
      If btrfs_decompress_buf2page() is handed a bio with its page in the
      middle of the working buffer, then we adjust the offset into the working
      buffer. After we copy into the bio, we advance the iterator by the
      number of bytes we copied. Then, we have some logic to handle the case
      of discontiguous pages and adjust the offset into the working buffer
      again. However, if we didn't advance the bio to a new page, we may enter
      this case in error, essentially repeating the adjustment that we already
      made when we entered the function. The end result is bogus data in the
      bio.
      
      Previously, we only checked for this case when we advanced to a new
      page, but the conversion to bio iterators changed that. This restores
      the old, correct behavior.
      
      A case I saw when testing with zlib was:
      
          buf_start = 42769
          total_out = 46865
          working_bytes = total_out - buf_start = 4096
          start_byte = 45056
      
      The condition (total_out > start_byte && buf_start < start_byte) is
      true, so we adjust the offset:
      
          buf_offset = start_byte - buf_start = 2287
          working_bytes -= buf_offset = 1809
          current_buf_start = buf_start = 42769
      
      Then, we copy
      
          bytes = min(bvec.bv_len, PAGE_SIZE - buf_offset, working_bytes) = 1809
          buf_offset += bytes = 4096
          working_bytes -= bytes = 0
          current_buf_start += bytes = 44578
      
      After bio_advance(), we are still in the same page, so start_byte is the
      same. Then, we check (total_out > start_byte && current_buf_start < start_byte),
      which is true! So, we adjust the values again:
      
          buf_offset = start_byte - buf_start = 2287
          working_bytes = total_out - start_byte = 1809
          current_buf_start = buf_start + buf_offset = 45056
      
      But note that working_bytes was already zero before this, so we should
      have stopped copying.
      
      Fixes: 974b1adc ("btrfs: use bio iterators for the decompression handlers")
      Reported-by: NPat Erley <pat-lkml@erley.org>
      Reviewed-by: NChris Mason <clm@fb.com>
      Signed-off-by: NOmar Sandoval <osandov@fb.com>
      Signed-off-by: NChris Mason <clm@fb.com>
      Reviewed-by: NLiu Bo <bo.li.liu@oracle.com>
      Tested-by: NLiu Bo <bo.li.liu@oracle.com>
      6e78b3f7
    • L
      Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net · 1ee18329
      Linus Torvalds 提交于
      Pull networking fixes from David Miller:
      
       1) If the timing is wrong we can indefinitely stop generating new ipv6
          temporary addresses, from Marcus Huewe.
      
       2) Don't double free per-cpu stats in ipv6 SIT tunnel driver, from Cong
          Wang.
      
       3) Put protections in place so that AF_PACKET is not able to submit
          packets which don't even have a link level header to drivers. From
          Willem de Bruijn.
      
       4) Fix memory leaks in ipv4 and ipv6 multicast code, from Hangbin Liu.
      
       5) Don't use udp_ioctl() in l2tp code, UDP version expects a UDP socket
          and that doesn't go over very well when it is passed an L2TP one.
          Fix from Eric Dumazet.
      
       6) Don't crash on NULL pointer in phy_attach_direct(), from Florian
          Fainelli.
      
      * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net:
        l2tp: do not use udp_ioctl()
        xen-netfront: Delete rx_refill_timer in xennet_disconnect_backend()
        NET: mkiss: Fix panic
        net: hns: Fix the device being used for dma mapping during TX
        net: phy: Initialize mdio clock at probe function
        igmp, mld: Fix memory leak in igmpv3/mld_del_delrec()
        xen-netfront: Improve error handling during initialization
        sierra_net: Skip validating irrelevant fields for IDLE LSIs
        sierra_net: Add support for IPv6 and Dual-Stack Link Sense Indications
        kcm: fix 0-length case for kcm_sendmsg()
        xen-netfront: Rework the fix for Rx stall during OOM and network stress
        net: phy: Fix PHY module checks and NULL deref in phy_attach_direct()
        net: thunderx: Fix PHY autoneg for SGMII QLM mode
        net: dsa: Do not destroy invalid network devices
        ping: fix a null pointer dereference
        packet: round up linear to header len
        net: introduce device min_header_len
        sit: fix a double free on error path
        lwtunnel: valid encap attr check should return 0 when lwtunnel is disabled
        ipv6: addrconf: fix generation of new temporary addresses
      1ee18329
    • L
      Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dledford/rdma · a9dbf5c8
      Linus Torvalds 提交于
      Pull rdma fixes from Doug Ledford:
       "Third round of -rc fixes for 4.10 kernel:
      
         - two security related issues in the rxe driver
      
         - one compile issue in the RDMA uapi header"
      
      * tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dledford/rdma:
        RDMA: Don't reference kernel private header from UAPI header
        IB/rxe: Fix mem_check_range integer overflow
        IB/rxe: Fix resid update
      a9dbf5c8
    • L
      Merge branch 'i2c/for-current' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux · aca9fa0c
      Linus Torvalds 提交于
      Pull i2c bugfixes from Wolfram Sang:
       "Two bugfixes (proper IO mapping and use of mutex) for a driver feature
        we introduced in this cycle"
      
      * 'i2c/for-current' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux:
        i2c: piix4: Request the SMBUS semaphore inside the mutex
        i2c: piix4: Fix request_region size
      aca9fa0c
    • L
      Merge tag 'mmc-v4.10-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc · fc6f41ba
      Linus Torvalds 提交于
      Pull MMC host fix from Ulf Hansson:
       "mmci: Fix hang while waiting for busy-end interrupt"
      
      * tag 'mmc-v4.10-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc:
        mmc: mmci: avoid clearing ST Micro busy end interrupt mistakenly
      fc6f41ba
    • L
      Merge tag 'sound-4.10' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound · 1f369d16
      Linus Torvalds 提交于
      Pull sound fixes from Takashi Iwai:
       "Here are some last-minute fixes: two fixes for races in ALSA sequencer
        queue spotted by syzkaller, a revert for a regression of LINE6 driver
        (since 4.9), and a trivial new codec ID addition for Nvidia HDMI"
      
      * tag 'sound-4.10' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound:
        ALSA: hda - adding a new NV HDMI/DP codec ID in the driver
        ALSA: seq: Fix race at creating a queue
        Revert "ALSA: line6: Only determine control port properties if needed"
        ALSA: seq: Don't handle loop timeout at snd_seq_pool_done()
      1f369d16
    • L
      Merge tag 'nfsd-4.10-3' of git://linux-nfs.org/~bfields/linux · 7fe654dc
      Linus Torvalds 提交于
      Pull nfsd revert from Bruce Fields:
       "This patch turned out to have a couple problems. The problems are
        fixable, but at least one of the fixes is a little ugly. The original
        bug has always been there, so we can wait another week or two to get
        this right"
      
      * tag 'nfsd-4.10-3' of git://linux-nfs.org/~bfields/linux:
        nfsd: Revert "nfsd: special case truncates some more"
      7fe654dc
    • L
      Merge tag 'powerpc-4.10-4' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux · 3ebc7033
      Linus Torvalds 提交于
      Pull powerpc fixes friom Michael Ellerman:
       "Apologies for the late pull request, but Ben has been busy finding bugs.
      
         - Userspace was semi-randomly segfaulting on radix due to us
           incorrectly handling a fault triggered by autonuma, caused by a
           patch we merged earlier in v4.10 to prevent the kernel executing
           userspace.
      
         - We weren't marking host IPIs properly for KVM in the OPAL ICP
           backend.
      
         - The ERAT flushing on radix was missing an isync and was incorrectly
           marked as DD1 only.
      
         - The powernv CPU hotplug code was missing a wakeup type and failing
           to flush the interrupt correctly when using OPAL ICP
      
        Thanks to Benjamin Herrenschmidt"
      
      * tag 'powerpc-4.10-4' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux:
        powerpc/powernv: Properly set "host-ipi" on IPIs
        powerpc/powernv: Fix CPU hotplug to handle waking on HVI
        powerpc/mm/radix: Update ERAT flushes when invalidating TLB
        powerpc/mm: Fix spurrious segfaults on radix with autonuma
      3ebc7033
    • E
      l2tp: do not use udp_ioctl() · 72fb96e7
      Eric Dumazet 提交于
      udp_ioctl(), as its name suggests, is used by UDP protocols,
      but is also used by L2TP :(
      
      L2TP should use its own handler, because it really does not
      look the same.
      
      SIOCINQ for instance should not assume UDP checksum or headers.
      
      Thanks to Andrey and syzkaller team for providing the report
      and a nice reproducer.
      
      While crashes only happen on recent kernels (after commit
      7c13f97f ("udp: do fwd memory scheduling on dequeue")), this
      probably needs to be backported to older kernels.
      
      Fixes: 7c13f97f ("udp: do fwd memory scheduling on dequeue")
      Fixes: 85584672 ("udp: Fix udp_poll() and ioctl()")
      Signed-off-by: NEric Dumazet <edumazet@google.com>
      Reported-by: NAndrey Konovalov <andreyknvl@google.com>
      Acked-by: NPaolo Abeni <pabeni@redhat.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      72fb96e7
    • C
      Merge branch 'for-chris' of... · f3c7bfbd
      Chris Mason 提交于
      Merge branch 'for-chris' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux into for-linus-4.10
      f3c7bfbd