• 块设备调用逻辑(linux 5.4)


    [ 2133.109595]  dump_stack+0x6d/0x8b
    [ 2133.109596]  _rw_page+0xaf/0xbe [blk]
    [ 2133.109597]  mem_blk_submit_bio.cold+0xc2/0x16d [blk]
    [ 2133.109598]  generic_make_request+0xcf/0x320
    [ 2133.109599]  submit_bio+0x48/0x1d0
    [ 2133.109600]  ? bio_add_page+0x6a/0x90
    [ 2133.109600]  submit_bh_wbc+0x182/0x1b0
    [ 2133.109601]  __block_write_full_page+0x210/0x440
    [ 2133.109602]  ? touch_buffer+0x70/0x70
    [ 2133.109603]  block_write_full_page+0xb0/0x110
    [ 2133.109604]  blkdev_writepage+0x18/0x20
    [ 2133.109605]  __writepage+0x1d/0x50
    [ 2133.109606]  write_cache_pages+0x1ae/0x4b0
    [ 2133.109607]  ? __wb_calc_thresh+0x130/0x130
    [ 2133.109608]  ? block_write_end+0x38/0x90
    [ 2133.109609]  ? block_write_begin+0x4d/0xf0
    [ 2133.109610]  ? balance_dirty_pages_ratelimited+0x259/0x390
    [ 2133.109611]  ? generic_perform_write+0x13b/0x1c0
    [ 2133.109612]  generic_writepages+0x57/0x90
    [ 2133.109613]  blkdev_writepages+0xe/0x10
    [ 2133.109614]  do_writepages+0x43/0xd0
    [ 2133.109615]  ? blkdev_write_iter+0xcd/0x160
    [ 2133.109616]  __filemap_fdatawrite_range+0xd5/0x110
    [ 2133.109617]  file_write_and_wait_range+0x74/0xc0
    [ 2133.109618]  blkdev_fsync+0x1b/0x50
    [ 2133.109619]  vfs_fsync_range+0x49/0x80
    [ 2133.109619]  do_fsync+0x3d/0x70
    [ 2133.109620]  __x64_sys_fsync+0x14/0x20
    [ 2133.109621]  do_syscall_64+0x57/0x190
    [ 2133.109622]  entry_SYSCALL_64_after_hwframe+0x5c/0xc1
    [ 2133.109623] RIP: 0033:0x7f68ba6bd1a7
    [ 2133.109623] Code: 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 64 8b 04 25 18 00 00 00 85 c0 75 10 b8 4a 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 41 c3 48 83 ec 18 89 7c 24 0c e8 23 f4 f7 ff
    [ 2133.109624] RSP: 002b:00007ffe75697478 EFLAGS: 00000246 ORIG_RAX: 000000000000004a
    [ 2133.109624] RAX: ffffffffffffffda RBX: 000055a9657ad5b0 RCX: 00007f68ba6bd1a7
    [ 2133.109625] RDX: 0000000000000000 RSI: 000055a9657ad5b0 RDI: 0000000000000003
    [ 2133.109625] RBP: 0000000000000000 R08: 0000000000000000 R09: 00007f68ba7952f0
    [ 2133.109625] R10: 000055a9657a7010 R11: 0000000000000246 R12: 0000000000000000
    [ 2133.109626] R13: 0000000000000000 R14: 00007ffe756974f8 R15: 000055a9657ac770
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    [  282.777255] CPU: 0 PID: 2801 Comm: mount Tainted: G           OE     5.4.233-20230608 #11
    [  282.777257] Hardware name: VMware, Inc. VMware20,1/440BX Desktop Reference Platform, BIOS VMW201.00V.20648489.B64.2210180829 10/18/2022
    [  282.777258] Call Trace:
    [  282.777262]  dump_stack+0x6d/0x8b
    [  282.777265]  spu_mem_blk_rw_page+0x48/0x5f [spu_blk]
    [  282.777269]  bdev_read_page+0x79/0xa0
    [  282.777272]  do_mpage_readpage+0x626/0x810
    [  282.777277]  ? lru_cache_add+0xe/0x10
    [  282.777280]  mpage_readpages+0xe4/0x1a0
    [  282.777284]  ? blkdev_direct_IO+0x4b0/0x4b0
    [  282.777288]  blkdev_readpages+0x1d/0x20
    [  282.777290]  read_pages+0x71/0x1a0
    [  282.777293]  __do_page_cache_readahead+0x12f/0x1a0
    [  282.777295]  force_page_cache_readahead+0x98/0x110
    [  282.777297]  page_cache_sync_readahead+0xaf/0xc0
    [  282.777300]  generic_file_read_iter+0x942/0xda0
    [  282.777302]  ? lru_cache_add_active_or_unevictable+0x3a/0xb0
    [  282.777304]  blkdev_read_iter+0x4a/0x60
    [  282.777307]  new_sync_read+0x122/0x1b0
    [  282.777310]  __vfs_read+0x29/0x40
    [  282.777312]  vfs_read+0xab/0x160
    [  282.777314]  ksys_read+0x67/0xe0
    [  282.777317]  __x64_sys_read+0x1a/0x20
    [  282.777320]  do_syscall_64+0x57/0x190
    [  282.777323]  entry_SYSCALL_64_after_hwframe+0x5c/0xc1
    [  282.777324] RIP: 0033:0x7f25b85c0fd2
    [  282.777326] Code: c0 e9 c2 fe ff ff 50 48 8d 3d aa cb 0a 00 e8 d5 1a 02 00 0f 1f 44 00 00 f3 0f 1e fa 64 8b 04 25 18 00 00 00 85 c0 75 10 0f 05 <48> 3d 00 f0 ff ff 77 56 c3 0f 1f 44 00 00 48 83 ec 28 48 89 54 24
    [  282.777327] RSP: 002b:00007ffd78506a58 EFLAGS: 00000246 ORIG_RAX: 0000000000000000
    [  282.777328] RAX: ffffffffffffffda RBX: 00007f25b7f88028 RCX: 00007f25b85c0fd2
    [  282.777329] RDX: 0000000000040000 RSI: 00007f25b7f88038 RDI: 0000000000000003
    [  282.777330] RBP: 000055cabafa39a0 R08: 00007f25b7f88010 R09: 0000000000000000
    [  282.777331] R10: 0000000000000022 R11: 0000000000000246 R12: 000000003ffc0000
    [  282.777333] R13: 0000000000040000 R14: 00007f25b7f88010 R15: 000055cabafa39f0
    [  282.777429] [spu_mem_blk_rw_page] cpu 0 pid 2801 comm mount             sector 2097032 page_address 0xffff987a23212000 op 0 page_idx 262129
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    
    static const struct block_device_operations xblk_fops = {
    	.owner = THIS_MODULE,
    #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0)
    	.submit_bio = mem_blk_submit_bio,
    #endif
    	.rw_page = mem_blk_rw_page,
    };
    
    static int mem_blk_disk_init(void)
    {
        int err = 0;
        xblk.file = filp_open( BLK_FILE_PATH, O_RDWR | O_CREAT, 0644);
        if ( IS_ERR(xblk.file) ) {
            pr_err("Failed to open file\n");
            err = PTR_ERR(xblk.file);
            return err;
        }
    
    	xblk_major = register_blkdev(0, "mem_blk");
    	if (xblk_major < 0) {
            filp_close( xblk.file, NULL );
    		pr_err("register_blkdev returns %d\n", xblk_major);
    		return xblk_major;
    	}
    #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 14, 0)
    	xblk.mem_blk_disk = blk_alloc_disk(NUMA_NO_NODE);
    #else
    	xblk.mem_blk_disk = alloc_disk(1);
    #endif
    	if (xblk.mem_blk_disk == NULL) {
    		pr_err("alloc_disk failed.");
            filp_close( xblk.file, NULL );
    		return -ENOMEM;
    	}
    	xblk.mem_blk_disk->major = xblk_major;
    	xblk.mem_blk_disk->first_minor = 0;
    	xblk.mem_blk_disk->minors = 1;
    	xblk.mem_blk_disk->fops = &xblk_fops;
    	xblk.mem_blk_disk->private_data = &xblk;
    	strlcpy(xblk.mem_blk_disk->disk_name, "mem_blk", 12);
    	set_capacity(xblk.mem_blk_disk, g_size_gb * 1024 * 1024 * 2); 
        // g_size_gb is in GB, sector size is 512B
    
    #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 14, 0)
    	xblk.mem_blk_disk->queue = xblk.mem_blk_queue;
    #endif
    	/* align partitions on 4k */
    	blk_queue_physical_block_size(xblk.mem_blk_disk->queue, PAGE_SIZE);
    	/* Tell the block layer that this is not a rotational device */
    	blk_queue_flag_set(QUEUE_FLAG_NONROT, xblk.mem_blk_disk->queue);
    	blk_queue_flag_clear(QUEUE_FLAG_ADD_RANDOM, xblk.mem_blk_disk->queue);
    
    	add_disk(xblk.mem_blk_disk);
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    struct bio_vec {
    	struct page	*bv_page;  //数据所在的页
    	unsigned int	bv_len; //数据长度
    	unsigned int	bv_offset;  //数据在页中的偏移
    };
    
    struct bvec_iter {
    	sector_t		bi_sector;	/* 扇区号*/
    	unsigned int		bi_size;	/* 数据段剩余个数*/
    
    	unsigned int		bi_idx;		/* current index into bvl_vec */
    
    	unsigned int            bi_bvec_done;	/* number of bytes completed in
    						   current bvec */
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    static blk_qc_t mem_blk_submit_bio(struct request_queue *queue, struct bio *bio)
    #endif
    {
    	sector_t sector = bio->bi_iter.bi_sector;
    	struct bio_vec bvec;
    	struct bvec_iter iter;
    
    	bio_for_each_segment(bvec, bio, iter) {
    		unsigned int len = bvec.bv_len;
    		int err;
    		// printk("[mem_blk_submit_bio] len %d offset %d sector %lld op %d\n", 
            //                         len, bvec.bv_offset, sector, bio_op(bio));
    		if (len != PAGE_SIZE) {
    			pr_info("[mem_blk_submit_bio] unexpected page size %d\n", len);
    			goto io_error;
    		}
    		//数据读写操作
    		if (err)
    			goto io_error;
    		sector += len >> SECTOR_SHIFT;
    	}
    	bio_endio(bio);
    	return BLK_QC_T_NONE;
    io_error:
    	bio_io_error(bio);
    	return BLK_QC_T_NONE;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
  • 相关阅读:
    C++ 二维差分 二维前缀和逆运算 差分矩阵
    【从零开始学微服务】01.微服务的过去与现在
    My Forty-first Page - 二叉树的最近公共祖先 - By Nicolas
    服务端测试与功能测试
    【Java】replace替换方法
    微信可以使用室内地图了!视频播放也允许缩放
    关于==和equals的问题
    tensorboard报错解决:No dashboards are active for the current data set
    3D孪生场景SDK:Viwer 孪生世界
    53_Pandas中的条件替换值(where, mask)
  • 原文地址:https://blog.csdn.net/bme314/article/details/132643870