• Maurizio Lombardi's avatar
    bio: modify __bio_add_page() to accept pages that don't start a new segment · fcbf6a08
    Maurizio Lombardi authored
    The original behaviour is to refuse to add a new page if the maximum
    number of segments has been reached, regardless of the fact the page we
    are going to add can be merged into the last segment or not.
    
    Unfortunately, when the system runs under heavy memory fragmentation
    conditions, a driver may try to add multiple pages to the last segment.
    The original code won't accept them and EBUSY will be reported to
    userspace.
    
    This patch modifies the function so it refuses to add a page only in case
    the latter starts a new segment and the maximum number of segments has
    already been reached.
    
    The bug can be easily reproduced with the st driver:
    
    1) set CONFIG_SCSI_MPT2SAS_MAX_SGE or CONFIG_SCSI_MPT3SAS_MAX_SGE  to 16
    2) modprobe st buffer_kbs=1024
    3) #dd if=/dev/zero of=/dev/st0 bs=1M count=10
       dd: error writing `/dev/st0': Device or resource busy
    Signed-off-by: default avatarMaurizio Lombardi <mlombard@redhat.com>
    Signed-off-by: default avatarMing Lei <ming.lei@canonical.com>
    Cc: Jet Chen <jet.chen@intel.com>
    Cc: Tomas Henzl <thenzl@redhat.com>
    Cc: Jens Axboe <axboe@kernel.dk>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarJens Axboe <axboe@fb.com>
    fcbf6a08
bio.c 51.2 KB