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

Reply via email to