simple block device - request processing in threads

Andras Pal apal at szofi.net
Sat Mar 4 15:54:17 EST 2017


Thanks, that was it! Therefore, it means that, i suppose, blk_rq_cur_sectors() 
is meaningless and bio's are needed to be used exclusively.

Andras

On Sat, 4 Mar 2017, Pranay Srivastava wrote:

> On Friday, March 3, 2017, Andras Pal <apal at szofi.net> wrote:
>> Dear All,
>>
>> with some experience in low-level C programming, I started to develop a
>> kernel module which allows I2C slave EEPROM-alike devices (EEPROMs, FRAMs,
>> BBRAMs, etc) to be accessed as block devices. Since the i/o transactions
> are
>> relatively slow (say, 40k/sec), i'm using kernel threads. However, it
> seems
>> that while the read (rq_data_dir(req)) == 0) operations are fine, write
>> operations (rq_data_dir != 0) seems to be lost. For instance, if I do `dd
>> bs=512 count=32 of=/dev/i2cblk0`, only the first 8 sectors are fetched by
>> blk_fetch_request(). I copy the critical/relevant/interesting parts after
> this
>> message. The code is based on drivers/block/nbd.c.
>>
>> In addition - according to printk()-based debugging - after each write
> request,
>> the kernel starts to access sectors in the order of 0, 24, 8, 56, 120,
> 64, 32
>> (with 8 sectors == 1 page per request). Maybe it seeks for some
> filesystems...?
>> Can this feature be turned off (like setting
>> disk->queue->backing_dev_info.ra_pages to zero in order to turn off
>> readaheaad)?
>>
>> thanks in advance, cheers, Andras
>>
>>
> /*****************************************************************************/
>>
>> static int i2cblk_process_io_request(struct i2cblk_device *device,struct
> request *req)
>> {
>>   int    ret;
>>
>>   /* i2cblk_transfer(): this function calls i2c_master_send/recv(), etc.
> */
>>
>>   ret=i2cblk_transfer(device, blk_rq_pos(req), blk_rq_cur_sectors(req),
>
> Shouldn't you be going over all bio(s)
> in this req?
>
>>                  bio_data(req->bio),
>>                  rq_data_dir(req));
>>
>>   return(ret);
>> }
>>
>> static void i2cblk_request(struct request_queue *q)
>> {
>>   struct request *req;
>>
>>   while ( (req=blk_fetch_request(q)) != NULL )
>>    {     struct  i2cblk_device   *device;
>>
>>          if ( req->cmd_type != REQ_TYPE_FS )
>>           {      __blk_end_request_all(req, -EIO);
>>                  continue;
>>           }
>>
>>          /* spin_unlock_irq(q->queue_lock); */
>>
>>          device=req->rq_disk->private_data;
>>
>>          spin_lock_irq(&device->active_lock);
>>          list_add_tail(&req->queuelist,&device->active_queue);
>>          spin_unlock_irq(&device->active_lock);
>>
>>          wake_up(&device->active_wq);
>>
>>          /* spin_lock_irq(q->queue_lock); */
>>    };
>>
>> }
>>
>> static void i2cblk_end_request(struct request *req)
>> {
>>   int                    error;
>>   struct request_queue   *q = req->q;
>>   unsigned long          flags;
>>
>>   error=(req->errors ? -EIO : 0);
>>
>>   spin_lock_irqsave(q->queue_lock, flags);
>>   __blk_end_request_all(req, error);
>>   spin_unlock_irqrestore(q->queue_lock, flags);
>> }
>>
>> static void i2cblk_handle_request(struct i2cblk_device *device,struct
> request *req)
>> {
>>   if ( i2cblk_process_io_request(device,req) )
>>          req->errors++;
>>
>>   i2cblk_end_request(req);
>>
>>   return;
>> }
>>
>> static int i2cblk_thread(void *data)
>> {
>>   struct i2cblk_device   *device = data;
>>   struct request         *req;
>>
>>   while ( ! kthread_should_stop() )
>>    {
>>          wait_event_interruptible(device->active_wq,kthread_should_stop()
> || (!list_empty(&device->active_queue)));
>>
>>          if ( list_empty(&device->active_queue) )
>>                  continue;
>>
>>          spin_lock_irq(&device->active_lock);
>>          req = list_entry(device->active_queue.next,struct
> request,queuelist);
>>          list_del_init(&req->queuelist);
>>          spin_unlock_irq(&device->active_lock);
>>
>>          i2cblk_handle_request(device,req);
>>    };
>>
>>   return(0);
>> }
>>
>>
>> _______________________________________________
>> Kernelnewbies mailing list
>> Kernelnewbies at kernelnewbies.org
>> https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
>>
>
> --
>        ---P.K.S
>



More information about the Kernelnewbies mailing list