Kernel crash - NULL pointer dereference when calling DEVICE_WRITE from KTHREAD in a USB device drive


 
Thread Tools Search this Thread
Top Forums UNIX for Advanced & Expert Users Kernel crash - NULL pointer dereference when calling DEVICE_WRITE from KTHREAD in a USB device drive
# 1  
Old 01-20-2014
Kernel crash - NULL pointer dereference when calling DEVICE_WRITE from KTHREAD in a USB device drive

I'm writing a simple USB driver to drive a stepper motor based on USB Skeleton 2.2 Driver, kernel 3.8. The basic version is running properly. As a advancement, I introduced KTHREAD to call the DEVICE_WRITE (skel_write) (), so that the driver will be available for other tasks & requests.
Calling procedure : USER (request) -> DEVICE_IOCTL -> KTHREAD -> DEVICE_WRITE.
In this scenario, when I call the DEVICE_WRITE multiple times from KTHREAD through a loop, everything works fine. Then after some iterations, kernel gets messed up, upon seeing the log file, the error is :
Code:
Dec 30 01:15:14 mit kernel: [  962.316843] device_write(efed1180,2,10),ioused : 1
Dec 30 01:15:14 mit kernel: [  962.316900] data : 0, motor_cnt : 2, master_counter : 20
Dec 30 01:15:14 mit kernel: [  962.366498] data : 1, motor_cnt : 2, master_counter : 21
Dec 30 01:15:14 mit kernel: [  962.416116] Write over, going for sleep
Dec 30 01:15:14 mit kernel: [  962.416125] file : efed1180,data : 2,i : 11
Dec 30 01:15:14 mit kernel: [  962.416128] device_write(efed1180,2,10),ioused : 1
Dec 30 01:15:14 mit kernel: [  962.416166] BUG: unable to handle kernel NULL pointer dereference at   (null)
Dec 30 01:15:14 mit kernel: [  962.416254] IP: [] skel_write+0xd7/0x360 [usbstep]
Dec 30 01:15:14 mit kernel: [  962.416294] *pdpt = 0000000000000000 *pde = f0002accf0002acc
Dec 30 01:15:14 mit kernel: [  962.416332] Oops: 0000 [#1] SMP
Dec 30 01:15:14 mit kernel: [  962.416363] Modules linked in: usbstep(OF) parport_pc(F) ppdev(F) bnep rfcomm bluetooth snd_hda_codec_hdmi uvcvideo videobuf2_vmalloc videobuf2_memops videobuf2_core videodev snd_hda_codec_idt coretemp snd_hda_intel kvm snd_hda_codec snd_hwdep(F) snd_pcm(F) snd_page_alloc(F) joydev(F) snd_seq_midi(F) snd_seq_midi_event(F) snd_rawmidi(F) hp_wmi lib80211_crypt_tkip snd_seq(F) snd_seq_device(F) snd_timer(F) sparse_keymap radeon wl(POF) lib80211 ttm drm_kms_helper cfg80211 drm hp_accel lis3lv02d mei input_polldev wmi i2c_algo_bit video(F) intel_ips mac_hid snd(F) lpc_ich soundcore(F) microcode(F) lp(F) parport(F) psmouse(F) serio_raw(F) r8169 ahci(F) libahci(F) [last unloaded: usbstep]
Dec 30 01:15:14 mit kernel: [  962.416866] Pid: 2997, comm: mitesh Tainted: PF          O 3.8.0-26-generic #38-Ubuntu Hewlett-Packard HP ProBook 4520s/1411
Dec 30 01:15:14 mit kernel: [  962.416928] EIP: 0060:[] EFLAGS: 00010287 CPU: 2
Dec 30 01:15:14 mit kernel: [  962.416960] EIP is at skel_write+0xd7/0x360 [usbstep]
Dec 30 01:15:14 mit kernel: [  962.416989] EAX: f0665b84 EBX: 00000014 ECX: 000000d0 EDX: 00000014
Dec 30 01:15:14 mit kernel: [  962.417024] ESI: f0665b40 EDI: 00000000 EBP: efddbf40 ESP: efddbf04
Dec 30 01:15:14 mit kernel: [  962.417059]  DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068
Dec 30 01:15:14 mit kernel: [  962.417089] CR0: 8005003b CR2: 00000000 CR3: 019d1000 CR4: 000007f0
Dec 30 01:15:14 mit kernel: [  962.417124] DR0: 00000000 DR1: 00000000 DR2: 00000000 DR3: 00000000
Dec 30 01:15:14 mit kernel: [  962.417158] DR6: ffff0ff0 DR7: 00000400
Dec 30 01:15:14 mit kernel: [  962.417181] Process mitesh (pid: 2997, ti=efdda000 task=f0bed9b0 task.ti=efdda000)
Dec 30 01:15:14 mit kernel: [  962.417223] Stack:
Dec 30 01:15:14 mit kernel: [  962.417236]  f0665b84 efddbf58 efddbf58 0000000a 00000001 efddbf58 00000000 efddbf40
Dec 30 01:15:14 mit kernel: [  962.417301]  c1609d81 00000002 f06c5d40 00000014 0000000c efddbf58 f1487408 efddbf6c
Dec 30 01:15:14 mit kernel: [  962.417398]  f8585546 00000000 efed1180 efddbf58 0000000b f6eb0032 aa092dff f6eb7ebc
Dec 30 01:15:14 mit kernel: [  962.417475] Call Trace:
Dec 30 01:15:14 mit kernel: [  962.417504]  [] ? printk+0x4d/0x4f
Dec 30 01:15:14 mit kernel: [  962.417559]  [] tele+0x86/0xc0 [usbstep]
Dec 30 01:15:14 mit kernel: [  962.417618]  [] ? skel_write+0x360/0x360 [usbstep]
Dec 30 01:15:14 mit kernel: [  962.417691]  [] kthread+0x94/0xa0
Dec 30 01:15:14 mit kernel: [  962.417744]  [] ? __hrtimer_start_range_ns+0x2e0/0x460
Dec 30 01:15:14 mit kernel: [  962.417819]  [] ret_from_kernel_thread+0x1b/0x28
Dec 30 01:15:14 mit kernel: [  962.417886]  [] ? kthread_create_on_node+0xc0/0xc0
Dec 30 01:15:14 mit kernel: [  962.417951] Code: c0 89 c6 0f 84 83 01 00 00 83 c3 0a b8 00 0e 00 00 81 fb 00 0e 00 00 b9 d0 00 00 00 0f 46 c3 89 45 f0 8d 46 44 8b 55 f0 89 04 24 <8b> 07 e8 52 9f ee c8 85 c0 89 45 e4 0f 84 0f 01 00 00 8d 47 54
Dec 30 01:15:14 mit kernel: [  962.418433] EIP: [] skel_write+0xd7/0x360 [usbstep] SS:ESP 0068:efddbf04
Dec 30 01:15:14 mit kernel: [  962.418530] CR2: 0000000000000000
Dec 30 01:15:14 mit kernel: [  962.433930] ---[ end trace 63245eeeb64414aa ]---

Here goes the code : KTHREAD
Code:
int tele(void *__tele_data) {
        struct tele_data *tele_data = __tele_data;
        int i=0;
        char *dptr=NULL;
        char numb[4];
        sprintf(numb,"%d",tele_data->num);
        dptr=numb;
        for(i=0;i<30;i++) {
        is_ioctl_used=1;
                printk("file : %p,data : %s,i : %d\n", tele_data->file,dptr,i);
                skel_write(tele_data->file,(char *)dptr, 10, 0);
                printk("Write over, going for sleep\n");
        }
        return 0;
}

DEVICE_WRITE -
Code:
static ssize_t skel_write(struct file *file, const char *user_buffer,
                      size_t count, loff_t *ppos)
{
    struct usb_skel *dev;
    int retval = 0,i = 0,motor_count,dir=0;
    struct urb *urb = NULL;
    char *buf = NULL;
    char *buf1 = NULL;
    size_t writesize = min(count+10, (size_t)MAX_TRANSFER);
    printk(KERN_INFO "device_write(%p,%s,%d),ioused : %d\n", file, user_buffer, count,is_ioctl_used);
    dev = file->private_data;
    // verify that we actually have some data to write 
    if (count == 0)
            goto exit;
    /*
     * limit the number of URBs in flight to stop a user from using up all
     * RAM
     */
    if (!(file->f_flags & O_NONBLOCK)) {
            if (down_interruptible(&dev->limit_sem)) {
                    retval = -ERESTARTSYS;
                    goto exit;
            }
    } else {
            if (down_trylock(&dev->limit_sem)) {
                    retval = -EAGAIN;
                    goto exit;
            }
    }
    spin_lock_irq(&dev->err_lock);
    retval = dev->errors;
if (retval < 0) {
            // any error is reported once 
            dev->errors = 0;
            // to preserve notifications about reset 
            retval = (retval == -EPIPE) ? retval : -EIO;
    }
    spin_unlock_irq(&dev->err_lock);
    if (retval < 0)
            goto error;
    /* create a urb, and a buffer for it, and copy the data to the urb */
    buf1=(char *)kmalloc(sizeof(char)*20,GFP_KERNEL);  //Allocate 2nd buffer.
    if(is_ioctl_used) {   //Whether the write function is called from IOCTL or Directly (echo > /dev/stepper)
            sprintf(buf1,user_buffer);
    } else {
            if (copy_from_user(buf1, user_buffer,count)) {
                    retval = -EFAULT;
                    goto error;
            }
    }
    motor_count=simple_strtol(buf1,NULL,10);
    if(motor_count<0) {  //Rotation counts of stepper motor.
            motor_count=motor_count * -1;  //If motor_count<0 then rotate in anti-clock direction.
            dir=1;
    }
            urb = usb_alloc_urb(0, GFP_KERNEL);
            if (!urb) {
                    retval = -ENOMEM;
                    goto error;
            }
            buf = usb_alloc_coherent(dev->udev, writesize, GFP_KERNEL,
                            &urb->transfer_dma);
     if (!buf) {
                    retval = -ENOMEM;
                    goto error;
            }
            /* this lock makes sure we don't submit URBs to gone devices */
                    mutex_lock(&dev->io_mutex);
            if (!dev->interface) {          /* disconnect() was called */
                    mutex_unlock(&dev->io_mutex);
                    retval = -ENODEV;
                    goto error;
            }
            /* initialize the urb properly */
            usb_fill_int_urb(urb, dev->udev,
                            usb_sndintpipe(dev->udev, dev->bulk_out_endpointAddr),
                            buf, writesize, skel_write_bulk_callback, dev,dev->bInterval);
            urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
            usb_anchor_urb(urb, &dev->submitted);
    for(i=0;i<motor_count;i++) {  //Loop to rotate motor based on counts.
            printk("data : %d, motor_cnt : %d, master_counter : %d\n",ptr->data,motor_count,master_counter);
            if(dir==0) ptr=ptr->next;
            else ptr=ptr->prev;
            // Fill the buffers.
            buf[0]=0x01;
            buf[1]=0;
            buf[2]=ptr->data;
            /* send the data out the bulk port */
            retval = usb_submit_urb(urb, GFP_KERNEL);
    if (retval) {
                            dev_err(&dev->interface->dev,
                                            "%s - failed submitting write urb, error %d\n",
                                            __func__, retval);
                            mutex_unlock(&dev->io_mutex);
                            goto error_unanchor;
                    }
            if(++master_counter && master_counter > 47) master_counter=0;
            /*
             * release our reference to this urb, the USB core will eventually free
             * it entirely
             */
                            mdelay(50); //Delay is required to match with motor speed. 
            }
                    mutex_unlock(&dev->io_mutex);
                    usb_free_coherent(dev->udev, writesize, buf, urb->transfer_dma);
                    kfree(buf1);
                    usb_free_urb(urb);
                    is_ioctl_used=0;
            return writesize;
error_unanchor:
            usb_unanchor_urb(urb);
error:
    if (urb) {
            usb_free_coherent(dev->udev, writesize, buf, urb->transfer_dma);
            usb_free_urb(urb);
    }
    up(&dev->limit_sem);
exit:
    return retval;
}

I'm new to kernel programming and might be missing out something.
Thankyou for your support and time.
Regards,
Mitesh
Login or Register to Ask a Question

Previous Thread | Next Thread

9 More Discussions You Might Find Interesting

1. UNIX for Advanced & Expert Users

Get pointer for existing device class (struct class) in Linux kernel module

Hi all! I am trying to register a device in an existing device class, but I am having trouble getting the pointer to an existing class. I can create a class in a module, get the pointer to it and then use it to register the device with: *cl = class_create(THIS_MODULE, className);... (0 Replies)
Discussion started by: hdaniel@ualg.pt
0 Replies

2. Solaris

dedicated crash dump device

Hello Guys, I need a little help here. I have been studying crash dump and per what I am reading, you can dedicate a slice to use as a dump device. Now when you dedicate this slice, do you have to : 1) create a mount point? 2) add entry in /etc/vfstab? 3) is this slice wu or wm? 4) should... (3 Replies)
Discussion started by: cjashu
3 Replies

3. Emergency UNIX and Linux Support

HP-UX 11iv3 crash on integrity bl870c during os kernel boot

I have a problem it seems to me as kernel panic during os booting i attached screen shots for the error (7 Replies)
Discussion started by: h@foorsa.biz
7 Replies

4. Programming

C++ segmentation fault while checking for null pointer

void disptree(node *ptr) { if ((ptr->left) !=NULL) disptree(ptr->left); cout<<"Position:"<<ptr->pos<<" Data:"<<ptr->data<<endl; if ((ptr->right)!=NULL; disptree(ptr->right); } i'm getting a segmentation fault at the red line. i cannot understand what's the problem.... (3 Replies)
Discussion started by: vijaymrt
3 Replies

5. Solaris

Usb Device

AM TRYING TO CONNECT A USB EXTERNAL DRIVE FOR BACKUP,THE USB SLOT IS AVAILABLE,BUT I DONT KNOW IF IT IS READY WHEN I CONNECT IT,AND WHAT COMMANDS DO I NEED. tHANKS (10 Replies)
Discussion started by: tomjones
10 Replies

6. SCO

mounting USB floppy drive /Flash drive in OSR 6.0

Can anybody help me out to mount USB flash /floppy drive in sco openserver 6.0 . (5 Replies)
Discussion started by: sureshdrajan
5 Replies

7. IP Networking

Could a tcp issue be causing a null pointer exception?

The client's app gets a 'suspend error' which they say is due to a null pointer exception. Application people say nothing's wrong with the app. Network people say the network's fine. I'm supposed to see what's wrong with the system to be causing this error. I checked the NIC card settings, which... (1 Reply)
Discussion started by: pmichner
1 Replies

8. Programming

A Pointer to non-Virtual Address, and All of my Hard drive

How do I get a pointer to any 32 bit address on my hard drive, in which I then could read that memory or write to that memory address? And, while the subject is on, how do get a 32 bit pointer in RAM also, in which I can do the same? I'm using C and Objective-C with gcc on an iBook G4. A... (9 Replies)
Discussion started by: xcoder66
9 Replies

9. UNIX for Dummies Questions & Answers

Crash Kills Printer Device

A user accidentally unplugged her server from the wall. She has rebooted twice, but the system does not recognize the default printer device, which previously was lp02. There is a file which reads /dev/lp0 and then garble. I'm a total newbie at all of this, with some Unix experience many,... (2 Replies)
Discussion started by: ckurt
2 Replies
Login or Register to Ask a Question