ll_rw_blk.c

来自「Linux块设备驱动源码」· C语言 代码 · 共 2,483 行 · 第 1/5 页

C
2,483
字号
 * @sectors:  number of sectors to complete * * Description: *   See blk_complete_barrier_rq(). This variant must be used if the caller *   holds the queue lock. **/int blk_complete_barrier_rq_locked(request_queue_t *q, struct request *rq,				   int sectors){	return __blk_complete_barrier_rq(q, rq, sectors, 1);}EXPORT_SYMBOL(blk_complete_barrier_rq_locked);/** * blk_queue_bounce_limit - set bounce buffer limit for queue * @q:  the request queue for the device * @dma_addr:   bus address limit * * Description: *    Different hardware can have different requirements as to what pages *    it can do I/O directly to. A low level driver can call *    blk_queue_bounce_limit to have lower memory pages allocated as bounce *    buffers for doing I/O to pages residing above @page. By default *    the block layer sets this to the highest numbered "low" memory page. **/void blk_queue_bounce_limit(request_queue_t *q, u64 dma_addr){	unsigned long bounce_pfn = dma_addr >> PAGE_SHIFT;	/*	 * set appropriate bounce gfp mask -- unfortunately we don't have a	 * full 4GB zone, so we have to resort to low memory for any bounces.	 * ISA has its own < 16MB zone.	 */	if (bounce_pfn < blk_max_low_pfn) {		BUG_ON(dma_addr < BLK_BOUNCE_ISA);		init_emergency_isa_pool();		q->bounce_gfp = GFP_NOIO | GFP_DMA;	} else		q->bounce_gfp = GFP_NOIO;	q->bounce_pfn = bounce_pfn;}EXPORT_SYMBOL(blk_queue_bounce_limit);/** * blk_queue_max_sectors - set max sectors for a request for this queue * @q:  the request queue for the device * @max_sectors:  max sectors in the usual 512b unit * * Description: *    Enables a low level driver to set an upper limit on the size of *    received requests. **/void blk_queue_max_sectors(request_queue_t *q, unsigned short max_sectors){	if ((max_sectors << 9) < PAGE_CACHE_SIZE) {		max_sectors = 1 << (PAGE_CACHE_SHIFT - 9);		printk("%s: set to minimum %d\n", __FUNCTION__, max_sectors);	}	q->max_sectors = q->max_hw_sectors = max_sectors;}EXPORT_SYMBOL(blk_queue_max_sectors);/** * blk_queue_max_phys_segments - set max phys segments for a request for this queue * @q:  the request queue for the device * @max_segments:  max number of segments * * Description: *    Enables a low level driver to set an upper limit on the number of *    physical data segments in a request.  This would be the largest sized *    scatter list the driver could handle. **/void blk_queue_max_phys_segments(request_queue_t *q, unsigned short max_segments){	if (!max_segments) {		max_segments = 1;		printk("%s: set to minimum %d\n", __FUNCTION__, max_segments);	}	q->max_phys_segments = max_segments;}EXPORT_SYMBOL(blk_queue_max_phys_segments);/** * blk_queue_max_hw_segments - set max hw segments for a request for this queue * @q:  the request queue for the device * @max_segments:  max number of segments * * Description: *    Enables a low level driver to set an upper limit on the number of *    hw data segments in a request.  This would be the largest number of *    address/length pairs the host adapter can actually give as once *    to the device. **/void blk_queue_max_hw_segments(request_queue_t *q, unsigned short max_segments){	if (!max_segments) {		max_segments = 1;		printk("%s: set to minimum %d\n", __FUNCTION__, max_segments);	}	q->max_hw_segments = max_segments;}EXPORT_SYMBOL(blk_queue_max_hw_segments);/** * blk_queue_max_segment_size - set max segment size for blk_rq_map_sg * @q:  the request queue for the device * @max_size:  max size of segment in bytes * * Description: *    Enables a low level driver to set an upper limit on the size of a *    coalesced segment **/void blk_queue_max_segment_size(request_queue_t *q, unsigned int max_size){	if (max_size < PAGE_CACHE_SIZE) {		max_size = PAGE_CACHE_SIZE;		printk("%s: set to minimum %d\n", __FUNCTION__, max_size);	}	q->max_segment_size = max_size;}EXPORT_SYMBOL(blk_queue_max_segment_size);/** * blk_queue_hardsect_size - set hardware sector size for the queue * @q:  the request queue for the device * @size:  the hardware sector size, in bytes * * Description: *   This should typically be set to the lowest possible sector size *   that the hardware can operate on (possible without reverting to *   even internal read-modify-write operations). Usually the default *   of 512 covers most hardware. **/void blk_queue_hardsect_size(request_queue_t *q, unsigned short size){	q->hardsect_size = size;}EXPORT_SYMBOL(blk_queue_hardsect_size);/* * Returns the minimum that is _not_ zero, unless both are zero. */#define min_not_zero(l, r) (l == 0) ? r : ((r == 0) ? l : min(l, r))/** * blk_queue_stack_limits - inherit underlying queue limits for stacked drivers * @t:	the stacking driver (top) * @b:  the underlying device (bottom) **/void blk_queue_stack_limits(request_queue_t *t, request_queue_t *b){	/* zero is "infinity" */	t->max_sectors = t->max_hw_sectors =		min_not_zero(t->max_sectors,b->max_sectors);	t->max_phys_segments = min(t->max_phys_segments,b->max_phys_segments);	t->max_hw_segments = min(t->max_hw_segments,b->max_hw_segments);	t->max_segment_size = min(t->max_segment_size,b->max_segment_size);	t->hardsect_size = max(t->hardsect_size,b->hardsect_size);}EXPORT_SYMBOL(blk_queue_stack_limits);/** * blk_queue_segment_boundary - set boundary rules for segment merging * @q:  the request queue for the device * @mask:  the memory boundary mask **/void blk_queue_segment_boundary(request_queue_t *q, unsigned long mask){	if (mask < PAGE_CACHE_SIZE - 1) {		mask = PAGE_CACHE_SIZE - 1;		printk("%s: set to minimum %lx\n", __FUNCTION__, mask);	}	q->seg_boundary_mask = mask;}EXPORT_SYMBOL(blk_queue_segment_boundary);/** * blk_queue_dma_alignment - set dma length and memory alignment * @q:     the request queue for the device * @mask:  alignment mask * * description: *    set required memory and length aligment for direct dma transactions. *    this is used when buiding direct io requests for the queue. * **/void blk_queue_dma_alignment(request_queue_t *q, int mask){	q->dma_alignment = mask;}EXPORT_SYMBOL(blk_queue_dma_alignment);/** * blk_queue_find_tag - find a request by its tag and queue * * @q:	 The request queue for the device * @tag: The tag of the request * * Notes: *    Should be used when a device returns a tag and you want to match *    it with a request. * *    no locks need be held. **/struct request *blk_queue_find_tag(request_queue_t *q, int tag){	struct blk_queue_tag *bqt = q->queue_tags;	if (unlikely(bqt == NULL || tag >= bqt->real_max_depth))		return NULL;	return bqt->tag_index[tag];}EXPORT_SYMBOL(blk_queue_find_tag);/** * __blk_queue_free_tags - release tag maintenance info * @q:  the request queue for the device * *  Notes: *    blk_cleanup_queue() will take care of calling this function, if tagging *    has been used. So there's no need to call this directly. **/static void __blk_queue_free_tags(request_queue_t *q){	struct blk_queue_tag *bqt = q->queue_tags;	if (!bqt)		return;	if (atomic_dec_and_test(&bqt->refcnt)) {		BUG_ON(bqt->busy);		BUG_ON(!list_empty(&bqt->busy_list));		kfree(bqt->tag_index);		bqt->tag_index = NULL;		kfree(bqt->tag_map);		bqt->tag_map = NULL;		kfree(bqt);	}	q->queue_tags = NULL;	q->queue_flags &= ~(1 << QUEUE_FLAG_QUEUED);}/** * blk_queue_free_tags - release tag maintenance info * @q:  the request queue for the device * *  Notes: *	This is used to disabled tagged queuing to a device, yet leave *	queue in function. **/void blk_queue_free_tags(request_queue_t *q){	clear_bit(QUEUE_FLAG_QUEUED, &q->queue_flags);}EXPORT_SYMBOL(blk_queue_free_tags);static intinit_tag_map(request_queue_t *q, struct blk_queue_tag *tags, int depth){	struct request **tag_index;	unsigned long *tag_map;	int nr_ulongs;	if (depth > q->nr_requests * 2) {		depth = q->nr_requests * 2;		printk(KERN_ERR "%s: adjusted depth to %d\n",				__FUNCTION__, depth);	}	tag_index = kmalloc(depth * sizeof(struct request *), GFP_ATOMIC);	if (!tag_index)		goto fail;	nr_ulongs = ALIGN(depth, BITS_PER_LONG) / BITS_PER_LONG;	tag_map = kmalloc(nr_ulongs * sizeof(unsigned long), GFP_ATOMIC);	if (!tag_map)		goto fail;	memset(tag_index, 0, depth * sizeof(struct request *));	memset(tag_map, 0, nr_ulongs * sizeof(unsigned long));	tags->real_max_depth = depth;	tags->max_depth = depth;	tags->tag_index = tag_index;	tags->tag_map = tag_map;	return 0;fail:	kfree(tag_index);	return -ENOMEM;}/** * blk_queue_init_tags - initialize the queue tag info * @q:  the request queue for the device * @depth:  the maximum queue depth supported * @tags: the tag to use **/int blk_queue_init_tags(request_queue_t *q, int depth,			struct blk_queue_tag *tags){	int rc;	BUG_ON(tags && q->queue_tags && tags != q->queue_tags);	if (!tags && !q->queue_tags) {		tags = kmalloc(sizeof(struct blk_queue_tag), GFP_ATOMIC);		if (!tags)			goto fail;		if (init_tag_map(q, tags, depth))			goto fail;		INIT_LIST_HEAD(&tags->busy_list);		tags->busy = 0;		atomic_set(&tags->refcnt, 1);	} else if (q->queue_tags) {		if ((rc = blk_queue_resize_tags(q, depth)))			return rc;		set_bit(QUEUE_FLAG_QUEUED, &q->queue_flags);		return 0;	} else		atomic_inc(&tags->refcnt);	/*	 * assign it, all done	 */	q->queue_tags = tags;	q->queue_flags |= (1 << QUEUE_FLAG_QUEUED);	return 0;fail:	kfree(tags);	return -ENOMEM;}EXPORT_SYMBOL(blk_queue_init_tags);/** * blk_queue_resize_tags - change the queueing depth * @q:  the request queue for the device * @new_depth: the new max command queueing depth * *  Notes: *    Must be called with the queue lock held. **/int blk_queue_resize_tags(request_queue_t *q, int new_depth){	struct blk_queue_tag *bqt = q->queue_tags;	struct request **tag_index;	unsigned long *tag_map;	int max_depth, nr_ulongs;	if (!bqt)		return -ENXIO;	/*	 * if we already have large enough real_max_depth.  just	 * adjust max_depth.  *NOTE* as requests with tag value	 * between new_depth and real_max_depth can be in-flight, tag	 * map can not be shrunk blindly here.	 */	if (new_depth <= bqt->real_max_depth) {		bqt->max_depth = new_depth;		return 0;	}	/*	 * save the old state info, so we can copy it back	 */	tag_index = bqt->tag_index;	tag_map = bqt->tag_map;	max_depth = bqt->real_max_depth;	if (init_tag_map(q, bqt, new_depth))		return -ENOMEM;	memcpy(bqt->tag_index, tag_index, max_depth * sizeof(struct request *));	nr_ulongs = ALIGN(max_depth, BITS_PER_LONG) / BITS_PER_LONG;	memcpy(bqt->tag_map, tag_map, nr_ulongs * sizeof(unsigned long));	kfree(tag_index);	kfree(tag_map);	return 0;}EXPORT_SYMBOL(blk_queue_resize_tags);/** * blk_queue_end_tag - end tag operations for a request * @q:  the request queue for the device * @rq: the request that has completed * *  Description: *    Typically called when end_that_request_first() returns 0, meaning *    all transfers have been done for a request. It's important to call *    this function before end_that_request_last(), as that will put the *    request back on the free list thus corrupting the internal tag list. * *  Notes: *   queue lock must be held. **/void blk_queue_end_tag(request_queue_t *q, struct request *rq){	struct blk_queue_tag *bqt = q->queue_tags;	int tag = rq->tag;	BUG_ON(tag == -1);	if (unlikely(tag >= bqt->real_max_depth))		/*		 * This can happen after tag depth has been reduced.		 * FIXME: how about a warning or info message here?		 */		return;	if (unlikely(!__test_and_clear_bit(tag, bqt->tag_map))) {		printk(KERN_ERR "%s: attempt to clear non-busy tag (%d)\n",		       __FUNCTION__, tag);		return;	}	list_del_init(&rq->queuelist);	rq->flags &= ~REQ_QUEUED;	rq->tag = -1;	if (unlikely(bqt->tag_index[tag] == NULL))		printk(KERN_ERR "%s: tag %d is missing\n",		       __FUNCTION__, tag);	bqt->tag_index[tag] = NULL;	bqt->busy--;}EXPORT_SYMBOL(blk_queue_end_tag);/** * blk_queue_start_tag - find a free tag and assign it * @q:  the request queue for the device * @rq:  the block request that needs tagging * *  Description: *    This can either be used as a stand-alone helper, or possibly be *    assigned as the queue &prep_rq_fn (in which case &struct request *    automagically gets a tag assigned). Note that this function *    assumes that any type of request can be queued! if this is not *    true for your device, you must check the request type before *    calling this function.  The request will also be removed from *    the request queue, so it's the drivers responsibility to readd *    it if it should need to be restarted for some reason. * *  Notes: *   queue lock must be held. **/int blk_queue_start_tag(request_queue_t *q, struct request *rq){	struct blk_queue_tag *bqt = q->queue_tags;	int tag;	if (unlikely((rq->flags & REQ_QUEUED))) {		printk(KERN_ERR 		       "%s: request %p for device [%s] already tagged %d",		       __FUNCTION__, rq,		       rq->rq_disk ? rq->rq_disk->disk_name : "?", rq->tag);		BUG();	}	tag = find_first_zero_bit(bqt->tag_map, bqt->max_depth);	if (tag >= bqt->max_depth)		return 1;	__set_bit(tag, bqt->tag_map);	rq->flags |= REQ_QUEUED;	rq->tag = tag;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?