Find the answer to your Linux question:
Results 1 to 3 of 3
Hey guys, Ive been writing a kernel module to print per socket per process tcp stats using tcp_get_info function. The issue is i can get until the sock structure...but later ...
Enjoy an ad free experience by logging in. Not a member yet? Register.
  1. #1
    Just Joined!
    Join Date
    Apr 2011
    Posts
    2

    kernel module crashing on reading sock information


    Hey guys,

    Ive been writing a kernel module to print per socket per process tcp stats using tcp_get_info function. The issue is i can get until the sock structure...but later due to probably locking issues I am unable to get the module fully functional. It runs for about 10 minutes and then crashes off....Any help would be highly appreciated.

    The function code is pasted below.

    int process_tcpInfo(struct seq_file *s, struct task_struct *task){
    struct file *fArray;
    struct files_struct * files;
    struct dentry *dPointer;
    struct inode *iPointer;
    struct socket *stPointer;
    struct sock *skPointer;
    //struct tcp_info* tiTcpInfo;
    struct inet_sock *inSock;
    u16 dport;
    u16 sport;
    u32 daddr;
    u32 recvaddr;
    int wscale;
    int sack;
    unsigned int hash;
    struct inet_ehash_bucket *head;
    struct fdtable *fdt=NULL;
    struct tcp_info *tiTcpInfo;
    unsigned long flags;
    unsigned long readflags;
    int i=0;
    u8 rcv_wscale=0;
    u8 snd_wscale=0;
    tiTcpInfo=kmalloc(sizeof(struct tcp_info), GFP_KERNEL);
    if (!tiTcpInfo ){ // fatal kernel allocation error
    return -1;
    }
    if(task){
    get_task_struct(task);
    }

    files=get_files_struct(task);
    if(!files){
    put_task_struct(task);
    return 0;
    }

    //filp=fcheck_files(files, fd);

    if(files){
    //printk(KERN_INFO "seqtcpmod: reached line %d\n", __LINE__);
    fdt = files_fdtable(files);
    //printk(KERN_INFO "seqtcpmod: reached line %d\n", __LINE__);
    }
    if(fdt==NULL){
    //printk(KERN_INFO "seqtcpmod: reached line %d\n", __LINE__);
    put_files_struct(files);
    put_task_struct(task);
    return 0;
    }

    for(i=0;imax_fds;i++){
    spin_lock_irqsave(&files->file_lock, flags);
    fArray=rcu_dereference(fdt->fd[i]);
    if(!fArray){
    spin_unlock_irqrestore(&files->file_lock,flags);
    break;
    }
    get_file(fArray);
    dPointer = rcu_dereference(fArray->f_dentry);
    if(dPointer == NULL){
    spin_unlock_irqrestore(&files->file_lock,flags);
    fput(fArray);
    continue;
    }
    dPointer=dget(dPointer);
    iPointer = rcu_dereference(dPointer->d_inode);
    if(iPointer == NULL){
    spin_unlock_irqrestore(&files->file_lock,flags);
    put(dPointer);
    fput(fArray);
    continue;
    }
    igrab(iPointer);
    stPointer=rcu_dereference(SOCKET_I(iPointer));
    if(stPointer==NULL){
    spin_unlock_irqrestore(&files->file_lock,flags);
    iput(iPointer);
    dput(dPointer);
    fput(fArray);
    continue;
    }
    skPointer=rcu_dereference(stPointer->sk);
    if(skPointer == NULL){
    spin_unlock_irqrestore(&files->file_lock,flags);
    iput(SOCK_INODE(stPointer));
    dput(dPointer);
    fput(fArray);
    continue;
    }
    spin_unlock_irqrestore(&files->file_lock,flags);
    iput(SOCK_INODE(stPointer));
    dput(dPointer);
    fput(fArray);

    // PROBLEM CAUSING IF BLOCK

    if((stPointer->type == 1)&&((skPointer->sk_family==PF_INET)||(skPointer->sk_family==PF_INET6)||(skPointer->sk_family==AF_INET)||(skPointer->sk_family==AF_INET6))&& (skPointer)){

    local_bh_disable();
    head = inet_ehash_bucket(&tcp_hashinfo, hash);
    read_lock_irqsave(&head->lock,readflags);
    inSock=inet_sk(skPointer);
    dport=ntohs(inSock->dport);
    sport=ntohs(inSock->sport);
    daddr=ntohl(inSock->daddr);
    recvaddr=ntohl(inSock->rcv_saddr);
    tcp_get_info(skPointer, tiTcpInfo);
    read_unlock_irqrestore(&head->lock,readflags);
    local_bh_enable();
    if((tiTcpInfo->tcpi_options & TCPI_OPT_WSCALE )== TCPI_OPT_WSCALE){
    wscale=1;
    }else{
    wscale=0;
    }
    if((tiTcpInfo->tcpi_options & TCPI_OPT_SACK )== TCPI_OPT_SACK){
    sack=1;
    }else{
    sack=0;
    }
    rcv_wscale|=tiTcpInfo->tcpi_rcv_wscale;
    snd_wscale|=tiTcpInfo->tcpi_snd_wscale;
    if(tiTcpInfo!=NULL){
    seq_printf(s,"%d %s %d %d %d %u:%hu %u:%hu %hd %hd %hd %hd %hd %hd %hd %hd %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u\n",task->pid, task->comm, i, wscale,sack,recvaddr,sport,daddr,dport, tiTcpInfo->tcpi_state, tiTcpInfo->tcpi_ca_state, tiTcpInfo->tcpi_retransmits, tiTcpInfo->tcpi_probes, tiTcpInfo->tcpi_backoff, tiTcpInfo->tcpi_options, snd_wscale, rcv_wscale, tiTcpInfo->tcpi_rto, tiTcpInfo->tcpi_ato, tiTcpInfo->tcpi_snd_mss, tiTcpInfo->tcpi_rcv_mss, tiTcpInfo->tcpi_unacked, tiTcpInfo->tcpi_sacked, tiTcpInfo->tcpi_lost, tiTcpInfo->tcpi_retrans, tiTcpInfo->tcpi_fackets, tiTcpInfo->tcpi_last_data_sent, tiTcpInfo->tcpi_last_ack_sent, tiTcpInfo->tcpi_last_data_recv, tiTcpInfo->tcpi_last_ack_recv, tiTcpInfo->tcpi_pmtu, tiTcpInfo->tcpi_rcv_ssthresh, tiTcpInfo->tcpi_rtt, tiTcpInfo->tcpi_rttvar, tiTcpInfo->tcpi_snd_ssthresh, tiTcpInfo->tcpi_snd_cwnd, tiTcpInfo->tcpi_advmss, tiTcpInfo->tcpi_reordering, tiTcpInfo->tcpi_rcv_rtt, tiTcpInfo->tcpi_rcv_space, tiTcpInfo->tcpi_total_retrans);
    }

    }


    } // FOR LOOP ENDS HERE

    put_files_struct(files);
    put_task_struct(task);
    kfree(tiTcpInfo);
    return 1;
    }

  2. #2
    Linux Guru Rubberman's Avatar
    Join Date
    Apr 2009
    Location
    I can be found either 40 miles west of Chicago, in Chicago, or in a galaxy far, far away.
    Posts
    11,601
    PLEASE put your code inside code blocks, otherwise it is effectively impossible to read. Example:
    Code:
    /* This is a comment */
    int function(void)
    {
        /* This is inside a function */
        for (int i = 0; i < 10; i++)
        {
            /* this is inside a loop */
        }
    }
    Sometimes, real fast is almost as good as real time.
    Just remember, Semper Gumbi - always be flexible!

  3. #3
    Just Joined!
    Join Date
    Apr 2011
    Posts
    2
    Apologize for the inconvenience caused due to incorrect formatting. I hope the one below is fine. Still stuck at this. Thanks for your reponse.




    Code:
    
    int process_tcpInfo(struct seq_file *s, struct task_struct *task){ 
    struct file *fArray; 
    struct files_struct * files; 
    struct dentry *dPointer; 
    struct inode *iPointer; 
    struct socket *stPointer; 
    struct sock *skPointer; 
    //struct tcp_info* tiTcpInfo; 
    struct inet_sock *inSock; 
    u16 dport; 
    u16 sport; 
    u32 daddr; 
    u32 recvaddr; 
    int wscale; 
    int sack; 
    unsigned int hash; 
    struct inet_ehash_bucket *head; 
    struct fdtable *fdt=NULL; 
    struct tcp_info *tiTcpInfo; 
    unsigned long flags; 
    unsigned long readflags; 
    int i=0; 
    u8 rcv_wscale=0; 
    u8 snd_wscale=0; 
    tiTcpInfo=kmalloc(sizeof(struct tcp_info), GFP_KERNEL); 
    if (!tiTcpInfo ){ // fatal kernel allocation error 
                   return -1; 
    } 
    if(task){ 
                   get_task_struct(task); 
    } 
    
    files=get_files_struct(task); 
    if(!files){ 
                put_task_struct(task); 
                return 0; 
    } 
    
    if(files){ 
                  fdt = files_fdtable(files); 
    } 
    if(fdt==NULL){ 
                  put_files_struct(files); 
                  put_task_struct(task); 
                  return 0; 
    } 
    
    for(i=0;imax_fds;i++){ 
                   spin_lock_irqsave(&files->file_lock, flags); 
                   fArray=rcu_dereference(fdt->fd[i]); 
                   if(!fArray){ 
                          spin_unlock_irqrestore(&files->file_lock,flags); 
                          break; 
                    } 
                    get_file(fArray); 
                    dPointer = rcu_dereference(fArray->f_dentry); 
                    if(dPointer == NULL){ 
                             spin_unlock_irqrestore(&files->file_lock,flags); 
                             fput(fArray); 
                             continue; 
                    } 
                    dPointer=dget(dPointer); 
                    iPointer = rcu_dereference(dPointer->d_inode); 
                    if(iPointer == NULL){ 
                              spin_unlock_irqrestore(&files->file_lock,flags); 
                              put(dPointer); 
                              fput(fArray); 
                              continue; 
                    } 
                    igrab(iPointer); 
                    stPointer=rcu_dereference(SOCKET_I(iPointer)); 
                    if(stPointer==NULL){ 
                              spin_unlock_irqrestore(&files->file_lock,flags); 
                              iput(iPointer); 
                              dput(dPointer); 
                              fput(fArray); 
                              continue; 
                     } 
                     skPointer=rcu_dereference(stPointer->sk); 
                     if(skPointer == NULL){ 
                              spin_unlock_irqrestore(&files->file_lock,flags); 
                              iput(SOCK_INODE(stPointer)); 
                              dput(dPointer); 
                              fput(fArray); 
                              continue; 
                      } 
                     spin_unlock_irqrestore(&files->file_lock,flags); 
                     iput(SOCK_INODE(stPointer)); 
                     dput(dPointer); 
                     fput(fArray); 
    
    // PROBLEM CAUSING IF BLOCK 
                     if((stPointer->type == 1)&&((skPointer->sk_family==PF_INET)||(skPointer->sk_family==PF_INET6)||(skPointer->sk_family==AF_INET)||(skPointer->sk_family==AF_INET6))&& (skPointer)){ 
                                      local_bh_disable(); 
                                      head = inet_ehash_bucket(&tcp_hashinfo, hash); 
                                      read_lock_irqsave(&head->lock,readflags); 
                                      inSock=inet_sk(skPointer); 
                                      dport=ntohs(inSock->dport); 
                                      sport=ntohs(inSock->sport); 
                                      daddr=ntohl(inSock->daddr); 
                                      recvaddr=ntohl(inSock->rcv_saddr); 
                                      tcp_get_info(skPointer, tiTcpInfo); 
                                      read_unlock_irqrestore(&head->lock,readflags); 
                                      local_bh_enable(); 
                                      if((tiTcpInfo->tcpi_options & TCPI_OPT_WSCALE )== TCPI_OPT_WSCALE){ 
                                                       wscale=1; 
                                        }else{ 
                                                       wscale=0; 
                                      } 
                                      if((tiTcpInfo->tcpi_options & TCPI_OPT_SACK )== TCPI_OPT_SACK){ 
                                                       sack=1; 
                                      }else{ 
                                                       sack=0; 
                                      } 
                                      rcv_wscale|=tiTcpInfo->tcpi_rcv_wscale; 
                                      snd_wscale|=tiTcpInfo->tcpi_snd_wscale; 
                                      if(tiTcpInfo!=NULL){ 
                                                            seq_printf(s,"%d %s %d %d %d %u:%hu %u:%hu %hd %hd %hd %hd %hd %hd %hd %hd %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u\n",task->pid, task->comm, i, wscale,sack,recvaddr,sport,daddr,dport, tiTcpInfo->tcpi_state, tiTcpInfo->tcpi_ca_state, tiTcpInfo->tcpi_retransmits, tiTcpInfo->tcpi_probes, tiTcpInfo->tcpi_backoff, tiTcpInfo->tcpi_options, snd_wscale, rcv_wscale, tiTcpInfo->tcpi_rto, tiTcpInfo->tcpi_ato, tiTcpInfo->tcpi_snd_mss, tiTcpInfo->tcpi_rcv_mss, tiTcpInfo->tcpi_unacked, tiTcpInfo->tcpi_sacked, tiTcpInfo->tcpi_lost, tiTcpInfo->tcpi_retrans, tiTcpInfo->tcpi_fackets, tiTcpInfo->tcpi_last_data_sent, tiTcpInfo->tcpi_last_ack_sent, tiTcpInfo->tcpi_last_data_recv, tiTcpInfo->tcpi_last_ack_recv, tiTcpInfo->tcpi_pmtu, tiTcpInfo->tcpi_rcv_ssthresh, tiTcpInfo->tcpi_rtt, tiTcpInfo->tcpi_rttvar, tiTcpInfo->tcpi_snd_ssthresh, tiTcpInfo->tcpi_snd_cwnd, tiTcpInfo->tcpi_advmss, tiTcpInfo->tcpi_reordering, tiTcpInfo->tcpi_rcv_rtt, tiTcpInfo->tcpi_rcv_space, tiTcpInfo->tcpi_total_retrans); 
                                             }                  
    
                     } 
         } // FOR LOOP ENDS HERE 
    
       put_files_struct(files); 
       put_task_struct(task); 
       kfree(tiTcpInfo); 
       return 1; 
    }

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •