Re: [PATCH V4 4/5] md/raid10: improve raid10 discard request

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Xiao,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on song-md/md-next]
[also build test ERROR on v5.9-rc2 next-20200824]
[cannot apply to md/for-next]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Xiao-Ni/md-raid10-move-codes-related-with-submitting-discard-bio-into-one-function/20200824-131217
base:   git://git.kernel.org/pub/scm/linux/kernel/git/song/md.git md-next
config: microblaze-randconfig-r004-20200824 (attached as .config)
compiler: microblaze-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=microblaze 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@xxxxxxxxx>

All errors (new ones prefixed by >>):

   microblaze-linux-ld: drivers/gpu/drm/bridge/sil-sii8620.o: in function `sii8620_remove':
   drivers/gpu/drm/bridge/sil-sii8620.c:2354: undefined reference to `extcon_unregister_notifier'
   microblaze-linux-ld: drivers/gpu/drm/bridge/sil-sii8620.o: in function `sii8620_extcon_work':
   drivers/gpu/drm/bridge/sil-sii8620.c:2139: undefined reference to `extcon_get_state'
   microblaze-linux-ld: drivers/gpu/drm/bridge/sil-sii8620.o: in function `sii8620_extcon_init':
   drivers/gpu/drm/bridge/sil-sii8620.c:2179: undefined reference to `extcon_find_edev_by_node'
   microblaze-linux-ld: drivers/gpu/drm/bridge/sil-sii8620.c:2191: undefined reference to `extcon_register_notifier'
   microblaze-linux-ld: drivers/md/raid10.o: in function `raid10_handle_discard':
>> drivers/md/raid10.c:1624: undefined reference to `__umoddi3'
>> microblaze-linux-ld: drivers/md/raid10.c:1624: undefined reference to `__umoddi3'
   microblaze-linux-ld: drivers/md/raid10.c:1625: undefined reference to `__umoddi3'
   microblaze-linux-ld: drivers/md/raid10.c:1628: undefined reference to `__umoddi3'
   microblaze-linux-ld: drivers/md/raid10.c:1628: undefined reference to `__umoddi3'
   microblaze-linux-ld: drivers/md/raid10.o:drivers/md/raid10.c:1629: more undefined references to `__umoddi3' follow

# https://github.com/0day-ci/linux/commit/51a7d6125a8a7bdc849b2cae9cab78753c3ddb2c
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Xiao-Ni/md-raid10-move-codes-related-with-submitting-discard-bio-into-one-function/20200824-131217
git checkout 51a7d6125a8a7bdc849b2cae9cab78753c3ddb2c
vim +1624 drivers/md/raid10.c

  1572	
  1573	/* There are some limitations to handle discard bio
  1574	 * 1st, the discard size is bigger than stripe_size*2.
  1575	 * 2st, if the discard bio spans reshape progress, we use the old way to
  1576	 * handle discard bio
  1577	 */
  1578	static bool raid10_handle_discard(struct mddev *mddev, struct bio *bio)
  1579	{
  1580		struct r10conf *conf = mddev->private;
  1581		struct geom *geo = &conf->geo;
  1582		struct r10bio *r10_bio;
  1583	
  1584		int disk;
  1585		sector_t chunk;
  1586		int stripe_size;
  1587		sector_t split_size;
  1588	
  1589		sector_t bio_start, bio_end;
  1590		sector_t first_stripe_index, last_stripe_index;
  1591		sector_t start_disk_offset;
  1592		unsigned int start_disk_index;
  1593		sector_t end_disk_offset;
  1594		unsigned int end_disk_index;
  1595	
  1596		wait_barrier(conf);
  1597	
  1598		if (conf->reshape_progress != MaxSector &&
  1599		    ((bio->bi_iter.bi_sector >= conf->reshape_progress) !=
  1600		     conf->mddev->reshape_backwards))
  1601			geo = &conf->prev;
  1602	
  1603		stripe_size = geo->raid_disks << geo->chunk_shift;
  1604		bio_start = bio->bi_iter.bi_sector;
  1605		bio_end = bio_end_sector(bio);
  1606	
  1607		/* Maybe one discard bio is smaller than strip size or across one stripe
  1608		 * and discard region is larger than one stripe size. For far offset layout,
  1609		 * if the discard region is not aligned with stripe size, there is hole
  1610		 * when we submit discard bio to member disk. For simplicity, we only
  1611		 * handle discard bio which discard region is bigger than stripe_size*2
  1612		 */
  1613		if (bio_sectors(bio) < stripe_size*2)
  1614			goto out;
  1615	
  1616		if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery) &&
  1617			bio_start < conf->reshape_progress &&
  1618			bio_end > conf->reshape_progress)
  1619			goto out;
  1620	
  1621		/* For far offset layout, if bio is not aligned with stripe size, it splits
  1622		 * the part that is not aligned with strip size.
  1623		 */
> 1624		if (geo->far_offset && (bio_start % stripe_size)) {
  1625			split_size = (stripe_size - bio_start % stripe_size);
  1626			bio = raid10_split_bio(conf, bio, split_size, false);
  1627		}
  1628		if (geo->far_offset && (bio_end % stripe_size)) {
  1629			split_size = bio_sectors(bio) - (bio_end % stripe_size);
  1630			bio = raid10_split_bio(conf, bio, split_size, true);
  1631		}
  1632	
  1633		r10_bio = mempool_alloc(&conf->r10bio_pool, GFP_NOIO);
  1634		r10_bio->mddev = mddev;
  1635		r10_bio->state = 0;
  1636		r10_bio->sectors = 0;
  1637		memset(r10_bio->devs, 0, sizeof(r10_bio->devs[0]) * geo->raid_disks);
  1638	
  1639		wait_blocked_dev(mddev, r10_bio);
  1640	
  1641		r10_bio->master_bio = bio;
  1642	
  1643		bio_start = bio->bi_iter.bi_sector;
  1644		bio_end = bio_end_sector(bio);
  1645	
  1646		/* raid10 uses chunk as the unit to store data. It's similar like raid0.
  1647		 * One stripe contains the chunks from all member disk (one chunk from
  1648		 * one disk at the same HBA address). For layout detail, see 'man md 4'
  1649		 */
  1650		chunk = bio_start >> geo->chunk_shift;
  1651		chunk *= geo->near_copies;
  1652		first_stripe_index = chunk;
  1653		start_disk_index = sector_div(first_stripe_index, geo->raid_disks);
  1654		if (geo->far_offset)
  1655			first_stripe_index *= geo->far_copies;
  1656		start_disk_offset = (bio_start & geo->chunk_mask) +
  1657					(first_stripe_index << geo->chunk_shift);
  1658	
  1659		chunk = bio_end >> geo->chunk_shift;
  1660		chunk *= geo->near_copies;
  1661		last_stripe_index = chunk;
  1662		end_disk_index = sector_div(last_stripe_index, geo->raid_disks);
  1663		if (geo->far_offset)
  1664			last_stripe_index *= geo->far_copies;
  1665		end_disk_offset = (bio_end & geo->chunk_mask) +
  1666					(last_stripe_index << geo->chunk_shift);
  1667	
  1668		rcu_read_lock();
  1669		for (disk = 0; disk < geo->raid_disks; disk++) {
  1670			struct md_rdev *rdev = rcu_dereference(conf->mirrors[disk].rdev);
  1671			struct md_rdev *rrdev = rcu_dereference(
  1672				conf->mirrors[disk].replacement);
  1673	
  1674			r10_bio->devs[disk].bio = NULL;
  1675			r10_bio->devs[disk].repl_bio = NULL;
  1676	
  1677			if (rdev && (test_bit(Faulty, &rdev->flags)))
  1678				rdev = NULL;
  1679			if (rrdev && (test_bit(Faulty, &rrdev->flags)))
  1680				rrdev = NULL;
  1681			if (!rdev && !rrdev)
  1682				continue;
  1683	
  1684			if (rdev) {
  1685				r10_bio->devs[disk].bio = bio;
  1686				atomic_inc(&rdev->nr_pending);
  1687			}
  1688			if (rrdev) {
  1689				r10_bio->devs[disk].repl_bio = bio;
  1690				atomic_inc(&rrdev->nr_pending);
  1691			}
  1692		}
  1693		rcu_read_unlock();
  1694	
  1695		atomic_set(&r10_bio->remaining, 1);
  1696		for (disk = 0; disk < geo->raid_disks; disk++) {
  1697			sector_t dev_start, dev_end;
  1698			struct bio *mbio, *rbio = NULL;
  1699			struct md_rdev *rdev = rcu_dereference(conf->mirrors[disk].rdev);
  1700			struct md_rdev *rrdev = rcu_dereference(
  1701				conf->mirrors[disk].replacement);
  1702	
  1703			/*
  1704			 * Now start to calculate the start and end address for each disk.
  1705			 * The space between dev_start and dev_end is the discard region.
  1706			 *
  1707			 * For dev_start, it needs to consider three conditions:
  1708			 * 1st, the disk is before start_disk, you can imagine the disk in
  1709			 * the next stripe. So the dev_start is the start address of next
  1710			 * stripe.
  1711			 * 2st, the disk is after start_disk, it means the disk is at the
  1712			 * same stripe of first disk
  1713			 * 3st, the first disk itself, we can use start_disk_offset directly
  1714			 */
  1715			if (disk < start_disk_index)
  1716				dev_start = (first_stripe_index + 1) * mddev->chunk_sectors;
  1717			else if (disk > start_disk_index)
  1718				dev_start = first_stripe_index * mddev->chunk_sectors;
  1719			else
  1720				dev_start = start_disk_offset;
  1721	
  1722			if (disk < end_disk_index)
  1723				dev_end = (last_stripe_index + 1) * mddev->chunk_sectors;
  1724			else if (disk > end_disk_index)
  1725				dev_end = last_stripe_index * mddev->chunk_sectors;
  1726			else
  1727				dev_end = end_disk_offset;
  1728	
  1729			/* It only handles discard bio which size is >= stripe size, so
  1730			 * dev_end > dev_start all the time
  1731			 */
  1732			if (r10_bio->devs[disk].bio) {
  1733				mbio = bio_clone_fast(bio, GFP_NOIO, &mddev->bio_set);
  1734				mbio->bi_end_io = raid10_end_discard_request;
  1735				mbio->bi_private = r10_bio;
  1736				r10_bio->devs[disk].bio = mbio;
  1737				r10_bio->devs[disk].devnum = disk;
  1738				atomic_inc(&r10_bio->remaining);
  1739				md_submit_discard_bio(mddev, rdev, mbio, dev_start, dev_end);
  1740				bio_endio(mbio);
  1741			}
  1742			if (r10_bio->devs[disk].repl_bio) {
  1743				rbio = bio_clone_fast(bio, GFP_NOIO, &mddev->bio_set);
  1744				rbio->bi_end_io = raid10_end_discard_request;
  1745				rbio->bi_private = r10_bio;
  1746				r10_bio->devs[disk].repl_bio = rbio;
  1747				r10_bio->devs[disk].devnum = disk;
  1748				atomic_inc(&r10_bio->remaining);
  1749				md_submit_discard_bio(mddev, rrdev, rbio, dev_start, dev_end);
  1750				bio_endio(rbio);
  1751			}
  1752		}
  1753	
  1754		if (atomic_dec_and_test(&r10_bio->remaining)) {
  1755			md_write_end(r10_bio->mddev);
  1756			raid_end_bio_io(r10_bio);
  1757		}
  1758	
  1759		return 0;
  1760	out:
  1761		allow_barrier(conf);
  1762		return -EAGAIN;
  1763	}
  1764	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@xxxxxxxxxxxx

Attachment: .config.gz
Description: application/gzip


[Index of Archives]     [Linux RAID Wiki]     [ATA RAID]     [Linux SCSI Target Infrastructure]     [Linux Block]     [Linux IDE]     [Linux SCSI]     [Linux Hams]     [Device Mapper]     [Device Mapper Cryptographics]     [Kernel]     [Linux Admin]     [Linux Net]     [GFS]     [RPM]     [git]     [Yosemite Forum]


  Powered by Linux