On Tue, Dec 19, 2017 at 09:52:27AM -0800, rao.shoaib@xxxxxxxxxx wrote:OK.
@@ -129,6 +130,7 @@ int __kmem_cache_alloc_bulk(struct kmem_cache *s, gfp_t flags, size_t nr,Don't mix whitespace changes with significant patches.
for (i = 0; i < nr; i++) {
void *x = p[i] = kmem_cache_alloc(s, flags);
+
if (!x) {
__kmem_cache_free_bulk(s, i, p);
return 0;
I thought about it, but the interrupts are off due to acquiring the lock. No ?
+/* Main RCU function that is called to free RCU structures */Are you sure we can't call kfree_rcu() from interrupt context?
+static void
+__rcu_bulk_free(struct rcu_head *head, rcu_callback_t func, int cpu, bool lazy)
+{
+ unsigned long offset;
+ void *ptr;
+ struct rcu_bulk_free *rbf;
+ struct rcu_bulk_free_container *rbfc = NULL;
+
+ rbf = this_cpu_ptr(&cpu_rbf);
+
+ if (unlikely(!rbf->rbf_init)) {
+ spin_lock_init(&rbf->rbf_lock);
+ rbf->rbf_cpu = smp_processor_id();
+ rbf->rbf_init = true;
+ }
+
+ /* hold lock to protect against other cpu's */
+ spin_lock_bh(&rbf->rbf_lock);
The code does not change the grace period at all. In fact it adds to the grace period.
+ rbfc = rbf->rbf_container;You've broken RCU. Consider this scenario:
+ rbfc->rbfc_entries = 0;
+
+ if (rbf->rbf_list_head != NULL)
+ __rcu_bulk_schedule_list(rbf);
Thread 1 Thread 2 Thread 3
kfree_rcu(a)
schedule()
schedule()
gets pointer to b
kfree_rcu(b)
processes rcu callbacks
uses b
Thread 3 will free a and also free b, so thread 2 is going to use freed
memory and go splat. You can't batch up memory to be freed without
taking into account the grace periods.
I am kind of doing that but not on a per grace period but on a per cpu basis.
It might make sense for RCU to batch up all the memory it's going to free
in a single grace period, and hand it all off to slub at once, but that's
not what you've done here.
I am not sure I understand. If you had external memory you can easily do that.
I've been doing a lot of thinking about this because I really want a
way to kfree_rcu() an object without embedding a struct rcu_head in it.
But I see no way to do that today; even if we have an external memory
allocation to point to the object to be freed, we have to keep track of
the grace periods.