Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

scsi: sd: Enable sector size > PAGE_SIZE in SCSI sd driver

The WRITE SAME(16) and WRITE SAME(10) SCSI commands use a page from a
dedicated mempool (sd_page_pool) for their payload. This pool was
initialized to allocate single pages, which was sufficient as long as the
device sector size did not exceed the PAGE_SIZE.

Given that block layer now supports block size upto 64KB, i.e. beyond
PAGE_SIZE, initialize a large page pool in sd_probe() if a higher sector
device is attached, ensuring atomicity. Adapt sd_set_special_bvec() to use
large page pool when a higher sector size device is attached. Hence enable
sector sizes > PAGE_SIZE in SCSI sd driver.

Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
Signed-off-by: Swarna Prabhu <s.prabhu@samsung.com>
Co-developed-by: Pankaj Raghav <p.raghav@samsung.com>
Signed-off-by: Pankaj Raghav <p.raghav@samsung.com>
Link: https://patch.msgid.link/20260219043741.276729-2-sw.prabhu6@gmail.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>

authored by

Swarna Prabhu and committed by
Martin K. Petersen
7179e626 50209dec

+68 -12
+68 -12
drivers/scsi/sd.c
··· 107 107 static void sd_revalidate_disk(struct gendisk *); 108 108 109 109 static DEFINE_IDA(sd_index_ida); 110 + static DEFINE_MUTEX(sd_mutex_lock); 110 111 111 112 static mempool_t *sd_page_pool; 113 + static mempool_t *sd_large_page_pool; 114 + static atomic_t sd_large_page_pool_users = ATOMIC_INIT(0); 112 115 static struct lock_class_key sd_bio_compl_lkclass; 113 116 114 117 static const char *sd_cache_types[] = { 115 118 "write through", "none", "write back", 116 119 "write back, no read (daft)" 117 120 }; 121 + 122 + static int sd_large_pool_create(void) 123 + { 124 + mutex_lock(&sd_mutex_lock); 125 + if (!sd_large_page_pool) { 126 + sd_large_page_pool = mempool_create_page_pool( 127 + SD_MEMPOOL_SIZE, get_order(BLK_MAX_BLOCK_SIZE)); 128 + if (!sd_large_page_pool) { 129 + printk(KERN_ERR "sd: can't create large page mempool\n"); 130 + mutex_unlock(&sd_mutex_lock); 131 + return -ENOMEM; 132 + } 133 + } 134 + atomic_inc(&sd_large_page_pool_users); 135 + mutex_unlock(&sd_mutex_lock); 136 + return 0; 137 + } 138 + 139 + static void sd_large_pool_destroy(void) 140 + { 141 + mutex_lock(&sd_mutex_lock); 142 + if (atomic_dec_and_test(&sd_large_page_pool_users)) { 143 + mempool_destroy(sd_large_page_pool); 144 + sd_large_page_pool = NULL; 145 + } 146 + mutex_unlock(&sd_mutex_lock); 147 + } 118 148 119 149 static void sd_disable_discard(struct scsi_disk *sdkp) 120 150 { ··· 958 928 return protect; 959 929 } 960 930 961 - static void *sd_set_special_bvec(struct request *rq, unsigned int data_len) 931 + static void *sd_set_special_bvec(struct scsi_cmnd *cmd, unsigned int data_len) 962 932 { 963 933 struct page *page; 934 + struct request *rq = scsi_cmd_to_rq(cmd); 935 + struct scsi_device *sdp = cmd->device; 936 + unsigned sector_size = sdp->sector_size; 937 + unsigned int nr_pages = DIV_ROUND_UP(sector_size, PAGE_SIZE); 938 + int n; 964 939 965 - page = mempool_alloc(sd_page_pool, GFP_ATOMIC); 940 + if (sector_size > PAGE_SIZE) 941 + page = mempool_alloc(sd_large_page_pool, GFP_ATOMIC); 942 + else 943 + page = mempool_alloc(sd_page_pool, GFP_ATOMIC); 966 944 if (!page) 967 945 return NULL; 968 - clear_highpage(page); 946 + 947 + for (n = 0; n < nr_pages; n++) 948 + clear_highpage(page + n); 969 949 bvec_set_page(&rq->special_vec, page, data_len, 0); 970 950 rq->rq_flags |= RQF_SPECIAL_PAYLOAD; 971 951 return bvec_virt(&rq->special_vec); ··· 991 951 unsigned int data_len = 24; 992 952 char *buf; 993 953 994 - buf = sd_set_special_bvec(rq, data_len); 954 + buf = sd_set_special_bvec(cmd, data_len); 995 955 if (!buf) 996 956 return BLK_STS_RESOURCE; 997 957 ··· 1080 1040 u32 nr_blocks = sectors_to_logical(sdp, blk_rq_sectors(rq)); 1081 1041 u32 data_len = sdp->sector_size; 1082 1042 1083 - if (!sd_set_special_bvec(rq, data_len)) 1043 + if (!sd_set_special_bvec(cmd, data_len)) 1084 1044 return BLK_STS_RESOURCE; 1085 1045 1086 1046 cmd->cmd_len = 16; ··· 1107 1067 u32 nr_blocks = sectors_to_logical(sdp, blk_rq_sectors(rq)); 1108 1068 u32 data_len = sdp->sector_size; 1109 1069 1110 - if (!sd_set_special_bvec(rq, data_len)) 1070 + if (!sd_set_special_bvec(cmd, data_len)) 1111 1071 return BLK_STS_RESOURCE; 1112 1072 1113 1073 cmd->cmd_len = 10; ··· 1553 1513 static void sd_uninit_command(struct scsi_cmnd *SCpnt) 1554 1514 { 1555 1515 struct request *rq = scsi_cmd_to_rq(SCpnt); 1516 + struct scsi_device *sdp = SCpnt->device; 1517 + unsigned sector_size = sdp->sector_size; 1556 1518 1557 - if (rq->rq_flags & RQF_SPECIAL_PAYLOAD) 1558 - mempool_free(rq->special_vec.bv_page, sd_page_pool); 1519 + if (rq->rq_flags & RQF_SPECIAL_PAYLOAD) { 1520 + if (sector_size > PAGE_SIZE) 1521 + mempool_free(rq->special_vec.bv_page, sd_large_page_pool); 1522 + else 1523 + mempool_free(rq->special_vec.bv_page, sd_page_pool); 1524 + } 1559 1525 } 1560 1526 1561 1527 static bool sd_need_revalidate(struct gendisk *disk, struct scsi_disk *sdkp) ··· 2958 2912 "Sector size 0 reported, assuming 512.\n"); 2959 2913 } 2960 2914 2961 - if (sector_size != 512 && 2962 - sector_size != 1024 && 2963 - sector_size != 2048 && 2964 - sector_size != 4096) { 2915 + if (blk_validate_block_size(sector_size)) { 2965 2916 sd_printk(KERN_NOTICE, sdkp, "Unsupported sector size %d.\n", 2966 2917 sector_size); 2967 2918 /* ··· 4086 4043 sdkp->max_medium_access_timeouts = SD_MAX_MEDIUM_TIMEOUTS; 4087 4044 4088 4045 sd_revalidate_disk(gd); 4046 + if (sdp->sector_size > PAGE_SIZE) { 4047 + if (sd_large_pool_create()) { 4048 + error = -ENOMEM; 4049 + goto out_free_index; 4050 + } 4051 + } 4089 4052 4090 4053 if (sdp->removable) { 4091 4054 gd->flags |= GENHD_FL_REMOVABLE; ··· 4109 4060 if (error) { 4110 4061 device_unregister(&sdkp->disk_dev); 4111 4062 put_disk(gd); 4063 + if (sdp->sector_size > PAGE_SIZE) 4064 + sd_large_pool_destroy(); 4112 4065 goto out; 4113 4066 } 4114 4067 ··· 4263 4212 sd_shutdown(sdp); 4264 4213 4265 4214 put_disk(sdkp->disk); 4215 + 4216 + if (sdp->sector_size > PAGE_SIZE) 4217 + sd_large_pool_destroy(); 4266 4218 } 4267 4219 4268 4220 static inline bool sd_do_start_stop(struct scsi_device *sdev, bool runtime) ··· 4489 4435 4490 4436 scsi_unregister_driver(&sd_template); 4491 4437 mempool_destroy(sd_page_pool); 4438 + if (sd_large_page_pool) 4439 + mempool_destroy(sd_large_page_pool); 4492 4440 4493 4441 class_unregister(&sd_disk_class); 4494 4442