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