2
\$\begingroup\$

I wrote a function, read_fox_rcu() for getting an element from RCU-protected list in a linux device driver. read_fox_rcu() reads the first element, converts it to string , stores it to tmp and stores the first pointer to ppfox.

I wonder that I used locks (rcu_read_lock(), synchronize_rcu(), etc), in an appropriate way.

static int read_fox_rcu(struct fox ** ppfox, char *tmp, size_t size){
    struct fox *f;
    rcu_read_lock();
    f = list_first_or_null_rcu(&fox_list_rcu, struct fox, list);
    if (f==NULL) {
        rcu_read_unlock();
        return -1;
    }
    snprintf(tmp, size, "%lu/%lu/%d\t",
            f->tail_length, f->weight, f->is_fantastic);
    *ppfox = f;
    rcu_read_unlock();
    return 0;
}

#define MAX_BUF_SIZE    1024
static ssize_t show_pop_fox_r(struct device *dev, struct device_attribute *attr, char *buf)
{
    int ret;
    struct fox * f;
    char tmp[MAX_BUF_SIZE];

    if (read_fox_rcu(&f, tmp, MAX_BUF_SIZE)) {
        ret = scnprintf(buf, PAGE_SIZE, "failure on read_fox_rcu()\n");
        return ret;
    }
    list_del_rcu(&f->list);
    synchronize_rcu();
    kfree(f);

    ret = scnprintf(buf, PAGE_SIZE, "%s\n", tmp);
    return ret;
}

static DEVICE_ATTR(pop_fox_r, S_IRUGO, show_pop_fox_r, NULL);

dev_attr_pop_fox_r.attr is declared by DEVICE_ATTR. And pop_fox_r is created, by calling sysfs_create_group() in the probe function.

fox_list_rcu and struct fox is defined like below.

struct fox {
    size_t tail_length;
    size_t weight;
    bool is_fantastic;
    struct list_head list;
};

static LIST_HEAD(fox_list_rcu);
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.