ram based block dev driver -- timer function -- async processing

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi all
i have already posted this also .but still not solved ..really need help

MY aim :
in simple ram based block dev driver
wherein
in request function -- dequeue the req from req queue and add it to the linked list
then in the function triggered by timer
handle each req from the linked list
then blk_end_requets is called upon completion of request .


i have tried all possible code modifications so many of times but each time i have to reboot after crash ...and that too doesnt leave any log message
i am sending important parts of code it will be very kind if someone sees thru it some mistake i am making ...
.
i am highlighting error prone areas what i am guessing ..some prob in handle timer is there

Important point pl consider
the request processing code used in handle_timer has been successfully running
when i dont use that in timer and just process request segment by segment in normal request function only .
i guess some problem is with using __bio_kmap_atomic in timer function i guess is it ?


Important Data Structures are :

struct filtered_request_queue {
       spinlock_t lock;
        struct list_head link;
};/*this queue is in kernel space only */
                       
struct filtered_request {
         struct request* req;  
         struct list_head link;                  /* linked list of requests */
};                     

struct filtered_request_queue *frqp=NULL;
*************************************************************************************************************************
/*This function is called from init_module function */

static void init_filtered_linked_list(void)
{
/*
     just initializes frqp --- nothing more than  that  can be ignored
*/
        frqp=(struct filtered_request_queue*)kzalloc(sizeof(struct filtered_request_queue),GFP_KERNEL);
        INIT_LIST_HEAD(&(frqp->link));
        spin_lock_init(&(frqp->lock));
}



static void blkdev_req_fn(struct request_queue *q)
{
        struct request *req;
        struct filtered_request * my_req=NULL;
        unsigned long  flags=0;
        while((req = elv_next_request(q)) != NULL){
                if(!blk_fs_request(req)){
                        end_request(req, 0);
                        continue;
                }
                blkdev_dequeue_request(req);
               my_req = (struct filtered_request*)kzalloc(sizeof(struct filtered_request),GFP_ATOMIC);
                my_req->req=req;
                spin_lock_irqsave(&(frqp->lock),flags);
                list_add_tail(&(my_req->link),&(frqp->link));
                spin_unlock_irqrestore(&(frqp->lock),flags);
                printk(KERN_ALERT"i m going out of req function ");

        }//while
}


static void set_timer_req_process(void)
{
        init_timer(&timer);
        timer.function=handle_timer;
        timer.expires=jiffies+(5*HZ);
        add_timer(&timer);
}


static void handle_timer(unsigned long data)
{
        struct filtered_request *pos;
        struct request *my_req;
       
        struct bio_vec *bvec;
        struct req_iterator iter;
        struct bio *curr_bio;
        int i;
       
        sector_t sector ;
        int nsect = 0;
        unsigned long nr_bytes;
       
        unsigned long  flags;
        struct blkdev_device *dev;
        char *buffer;
        dev = dev_struct;

        spin_lock_irqsave(&(frqp->lock),flags);
        if(!list_empty(&(frqp->link)))
        {
                 list_for_each_entry(pos,&(frqp->link),link)
                {
                        my_req = pos->req;
                        sector=my_req->sector;
                        rq_for_each_segment(bvec, my_req, iter)
                        {
                            curr_bio = iter.bio;
                            i=iter.i;
                            buffer = __bio_kmap_atomic(curr_bio,i,KM_USER0);
                           data_transfer(dev,sector,bio_cur_sectors(curr_bio),buffer, bio_data_dir(curr_bio) == WRITE);
                           sector += bio_cur_sectors(curr_bio);
                           nsect += bio_cur_sectors(curr_bio);
                           __bio_kunmap_atomic(curr_bio, KM_USER0);
                        }
                      nr_bytes=nsect*512;
                      blk_end_request(my_req,0,nr_bytes)
                      pos->req=NULL;
                }//list_for_each_entry                 
       }//!list_empty 
      if(!list_empty(&(frqp->link)))
      {
          list_for_each_entry(pos,&(frqp->link),link)
                {
                       list_del(&(pos->link));        
                       kfree(pos);
                }
        }
        spin_unlock_irqrestore(&(frqp->lock),flags);
        set_timer_req_process();       
}//function


pl help i m stuck here totallygetting no clue at all ....same code works when used in normal request function ...but same code when processes request segment by segment in timer function ...crashes kernel ..pl pl help ...

**if someone needs i can send full code too ...



--
Thanks & Regards
Nidhi

[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux