* Since RCU callback function is called in bh,
* we need to defer the vfree to schedule_work
*/
-static void ipc_schedule_free(void* arg)
+static void ipc_schedule_free(struct rcu_head *head)
{
- struct ipc_rcu_vmalloc *free = arg;
+ struct ipc_rcu_vmalloc *free =
+ container_of(head, struct ipc_rcu_vmalloc, rcu);
INIT_WORK(&free->work, vfree, free);
schedule_work(&free->work);
}
+/**
+ * ipc_immediate_free - free ipc + rcu space
+ *
+ * Free from the RCU callback context
+ *
+ */
+static void ipc_immediate_free(struct rcu_head *head)
+{
+ struct ipc_rcu_kmalloc *free =
+ container_of(head, struct ipc_rcu_kmalloc, rcu);
+ kfree(free);
+}
+
+
+
void ipc_rcu_free(void* ptr, int size)
{
if (rcu_use_vmalloc(size)) {
struct ipc_rcu_vmalloc *free;
free = ptr - sizeof(*free);
- call_rcu(&free->rcu, ipc_schedule_free, free);
+ call_rcu(&free->rcu, ipc_schedule_free);
} else {
struct ipc_rcu_kmalloc *free;
free = ptr - sizeof(*free);
- /* kfree takes a "const void *" so gcc warns. So we cast. */
- call_rcu(&free->rcu, (void (*)(void *))kfree, free);
+ call_rcu(&free->rcu, ipc_immediate_free);
}
}