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\$

0

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.