1

I have read many posts about this same topic, but I am unable to find out what is exactly wrong with my sysfs implementation in my kernel module. I am trying to make a userspace program block on a poll untill the value changes in a sysfs file. Most people seem to not get blocking, I seem to not be able to get out of my blocking. Here is the relevent code:

kernel module:

static int sysfs_test = 88;


static ssize_t test_interrupts_show(struct device* dev, struct device_attribute* attr, const     char* buf)
{
    return scnprintf(buf, PAGE_SIZE, "%d\n", sysfs_test);
}

static ssize_t test_interrupts_store(struct device* dev, struct device_attribute* attr, const char* buf, size_t count)
{
    kstrtol(buf, 10, &sysfs_test);
    return count;
}

static DEVICE_ATTR(interrupts, S_IWUSR | S_IRUGO, test_interrupts_show, test_interrupts_store);

static int __init test_init(void)
{

int result;
if(dev_major)
{
    dev = MKDEV(dev_major, dev_minor);
    result = register_chrdev_region(dev, NUM_DEVICES, name);
} else {
    result = alloc_chrdev_region(&dev, dev_minor, NUM_DEVICES, name);
    dev_major = MAJOR(dev);
    dev_minor = MINOR(dev);
}

if(result < 0) {
    printk(KERN_WARNING "%s: can't get major %d\n", name, dev_major);
    return -1;
}
printk(KERN_NOTICE "%s: Major = %d, Minor = %d\n", name, dev_major, dev_minor);





// Register as character device
test_cdev = cdev_alloc();               
cdev_init(cajun_cdev, &test_fops);      // Initialize cdev structure
test_cdev->owner = THIS_MODULE;         // Add owner

result = cdev_add(test_cdev, dev,1);        // Tell kernel about our device

if(result)
{
    printk(KERN_NOTICE "Error %d adding cdev\n", result);
    goto OUT2;
}




// This stuff relates to sysfs:
ctest_class = class_create(THIS_MODULE, NAME);
if(IS_ERR(test_class))
{
    printk(KERN_ALERT "Failed to register device class\n");
    goto OUT2;
}

test_device = device_create(test_class, NULL, dev, NULL, NAME);
if(IS_ERR(test_device))
{
    printk(KERN_ALERT "Failed to create device\n");
    goto OUT3;
}

result = device_create_file(test_device, &dev_attr_interrupts);
if (result < 0)
{
    printk(KERN_ALERT "failed\n");
}



OUT3:
class_unregister(test_class);
class_destroy(test_class);
OUT2:
cdev_del(test_cdev);
OUT1:
unregister_chrdev_region(dev, NUM_DEVICES);

return -1;

}

Relevent userspace code:

char interrupts_path[] = "/sys/class/test_module/test_module/interrupts";

int main()
{
struct pollfd fds;
fds.fd = open(interrupts_path, O_RDWR | O_SYNC);
char dummy_buff[1];
read(fds.fd, dummy_buff, 1);
lseek(fds.fd, 0, SEEK_SET);
fds.events = POLLPRI;
printf("Polling for interrupt\n");
poll(&fds,1,-1);
printf("Interrupt occured\n");

return 0;
}

I run my userspace code in the background (./test &) and then I echo a new value into the sysfs file for interrupts. I am hopping for my userspace program to unblock and return when the value changes. What am I doing wrong here?

edit:

struct file_operations test_fops = {
    .owner              =   THIS_MODULE,
    .llseek             =   test_llseek,
    .read               =   test_read,
    .write              =   test_write,
    .unlocked_ioctl     =   test_ioctl,
    .open               =   test_open,
    .release            =   test_release

};
Cœur
  • 32,421
  • 21
  • 173
  • 232
whh4000
  • 795
  • 1
  • 8
  • 28
  • You should not expect this to work. Consider `netlink` sockets instead. – Brian Cain Jul 01 '14 at 13:31
  • Where is your file operations struct (test_fops)? – Brian Kocoloski Jul 01 '14 at 13:33
  • 1
    Strike that -- Use `sysfs_notify`. See also: http://stackoverflow.com/a/16404357/489590 – Brian Cain Jul 01 '14 at 13:38
  • I added the edit with the fops. This seems to be something that everyone uses, so why wouldn't it work. Ultimately it would not be triggered by an echo 1 > interrupts. I am just doing this as a test. – whh4000 Jul 01 '14 at 13:38
  • 1
    Why does this person not need sysfs_notify()? http://stackoverflow.com/questions/16442935/why-doesnt-this-call-to-poll-block-correctly-on-a-sysfs-device-attribute-file – whh4000 Jul 01 '14 at 13:41
  • 1
    The code in that question is non-functioning. The question-writer eventually solved the problem of poll NOT blocking, but didn't describe what other changes might have been necessary to make the whole thing work (adding `sysfs_notify()`, for instance). – Peter Jul 02 '14 at 13:52
  • possible duplicate of [Using the Linux sysfs\_notify call](http://stackoverflow.com/questions/16367623/using-the-linux-sysfs-notify-call) – Abhijeet Kasurde Jul 15 '14 at 09:19

0 Answers0