Using list_for_each_entry() in place of list_for_each_entry_rcu() ?

From: Tetsuo Handa
Date: Sat Nov 01 2014 - 07:59:19 EST


Excuse me for FAQ, Paul.
I want to confirm one thing for code optimization in LSM stacking.
( https://marc.info/?l=linux-security-module&m=141481716931982&w=2 )

In the following code, is there race window for seeing invalid
"struct list_head"->next value if we used list_for_each_entry()
in place of list_for_each_entry_rcu() ?

----------
/* Definition and declaration */
DEFINE_SPINLOCK(my_lock);
LIST_HEAD(my_list);
struct my_struct {
struct list_head list;
const unsigned long value;
} v1 = { .value = 1 }, v2 = { .value = 2 }, v3 = { .value = 3 };

/* Writer side */
void add_entry(struct my_struct *p) {
spin_lock(&my_lock);
list_add_tail_rcu(&p->list, &my_list);
spin_unlock(&my_lock);
}

void del_entry(struct my_struct *p) {
spin_lock(&my_lock);
list_del_rcu(&p->list);
spin_unlock(&my_lock);
}

/* Reader side */
unsigned long reader(void) {
struct my_struct *p;
unsigned long sum = 0;
list_for_each_entry_rcu(p, &my_list, list)
sum += p->value;
return sum;
}
----------

Assumptions are:

(1) v1, v2, v3 are statically allocated variables inside module,
while my_lock, my_list, add_entry(), del_entry(), reader()
are built-in.

(2) v1, v2, v3 are added to my_list only once upon module load

(3) v1, v2, v3 might be removed from my_list some time later after
module was loaded

Regards.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/