본문 바로가기

리눅스 커널/블록 멀티 큐

urgent queue 를 위한 tag 예약

1. request_queue 구조체 안에 int adm; 추가

   ->adm = 0; //일반 IO 큐로 다룬다.

   ->adm = 1; //관리자 큐로 다룬다.

 

2. request 구조체 안에 int urg; 추가

 

3. blk_mq_tags 구조체 안에 int nr_allocated; 추가

   ->read/write를 위해 할당한 태그 개수를 저장한다.

 

4. __blk_mq_get_tag() 수정

static int __blk_mq_get_tag(struct blk_mq_alloc_data *data,
			    struct sbitmap_queue *bt)
{
	if (!(data->flags & BLK_MQ_REQ_INTERNAL) &&
	    !hctx_may_queue(data->hctx, bt))
		return -1;
	if (!data->q->adm && current->prio >= 120 &&
		blk_mq_tags_from_data(data)->nr_allocated >= 980)
		return -1;
	if (data->shallow_depth)
		return __sbitmap_queue_get_shallow(bt, data->shallow_depth);
	else
		return __sbitmap_queue_get(bt);
}

 5. blk_mq_get_tag() 수정

    found_tag:

                 if (!data->q->adm && current->prio >= 120)

                        tag->nr_allocated += 1;

 

6. nvme_handle_cqe() 수정

    if (!req->q->adm && !req->urg)

           **(nvmeq->tags).nr_allocated -= 1;

 

7. blk_mq_rq_ctx_init() 수정

   if (!data->q->adm && current->prio < 120)

              rq->urg = 1;

   else

               rq->urg = 0;

 

8. nvme_alloc_admin_tags() 수정

   dev->ctrl.admin_q->adm = 1;

 

9. blk_mq_init_queue()

   q->adm = 0;

 

관리자 큐를 구분하기 위해 request_queue 안에 admin 정보를 둔다.

해당 request가 urgent한 것인지 판단하기 위해 urgent 정보를 둔다.