u_int16_t group_num;            /* number of this queue */
        u_int16_t flags;
        u_int8_t copy_mode;
+       struct rcu_head rcu;
 };
 
-static DEFINE_RWLOCK(instances_lock);
+static DEFINE_SPINLOCK(instances_lock);
 static atomic_t global_seq;
 
 #define INSTANCE_BUCKETS       16
        struct nfulnl_instance *inst;
 
        head = &instance_table[instance_hashfn(group_num)];
-       hlist_for_each_entry(inst, pos, head, hlist) {
+       hlist_for_each_entry_rcu(inst, pos, head, hlist) {
                if (inst->group_num == group_num)
                        return inst;
        }
 {
        struct nfulnl_instance *inst;
 
-       read_lock_bh(&instances_lock);
+       rcu_read_lock_bh();
        inst = __instance_lookup(group_num);
        if (inst)
                instance_get(inst);
-       read_unlock_bh(&instances_lock);
+       rcu_read_unlock_bh();
 
        return inst;
 }
 
+static void nfulnl_instance_free_rcu(struct rcu_head *head)
+{
+       kfree(container_of(head, struct nfulnl_instance, rcu));
+       module_put(THIS_MODULE);
+}
+
 static void
 instance_put(struct nfulnl_instance *inst)
 {
-       if (inst && atomic_dec_and_test(&inst->use)) {
-               kfree(inst);
-               module_put(THIS_MODULE);
-       }
+       if (inst && atomic_dec_and_test(&inst->use))
+               call_rcu_bh(&inst->rcu, nfulnl_instance_free_rcu);
 }
 
 static void nfulnl_timer(unsigned long data);
        struct nfulnl_instance *inst;
        int err;
 
-       write_lock_bh(&instances_lock);
+       spin_lock_bh(&instances_lock);
        if (__instance_lookup(group_num)) {
                err = -EEXIST;
                goto out_unlock;
        hlist_add_head(&inst->hlist,
                       &instance_table[instance_hashfn(group_num)]);
 
-       write_unlock_bh(&instances_lock);
+       spin_unlock_bh(&instances_lock);
 
        return inst;
 
 out_unlock:
-       write_unlock_bh(&instances_lock);
+       spin_unlock_bh(&instances_lock);
        return ERR_PTR(err);
 }
 
 static inline void
 instance_destroy(struct nfulnl_instance *inst)
 {
-       write_lock_bh(&instances_lock);
+       spin_lock_bh(&instances_lock);
        __instance_destroy(inst);
-       write_unlock_bh(&instances_lock);
+       spin_unlock_bh(&instances_lock);
 }
 
 static int
                int i;
 
                /* destroy all instances for this pid */
-               write_lock_bh(&instances_lock);
+               spin_lock_bh(&instances_lock);
                for  (i = 0; i < INSTANCE_BUCKETS; i++) {
                        struct hlist_node *tmp, *t2;
                        struct nfulnl_instance *inst;
                                        __instance_destroy(inst);
                        }
                }
-               write_unlock_bh(&instances_lock);
+               spin_unlock_bh(&instances_lock);
        }
        return NOTIFY_DONE;
 }
 
        for (st->bucket = 0; st->bucket < INSTANCE_BUCKETS; st->bucket++) {
                if (!hlist_empty(&instance_table[st->bucket]))
-                       return instance_table[st->bucket].first;
+                       return rcu_dereference_bh(instance_table[st->bucket].first);
        }
        return NULL;
 }
 
 static struct hlist_node *get_next(struct iter_state *st, struct hlist_node *h)
 {
-       h = h->next;
+       h = rcu_dereference_bh(h->next);
        while (!h) {
                if (++st->bucket >= INSTANCE_BUCKETS)
                        return NULL;
 
-               h = instance_table[st->bucket].first;
+               h = rcu_dereference_bh(instance_table[st->bucket].first);
        }
        return h;
 }
 }
 
 static void *seq_start(struct seq_file *seq, loff_t *pos)
-       __acquires(instances_lock)
+       __acquires(rcu_bh)
 {
-       read_lock_bh(&instances_lock);
+       rcu_read_lock_bh();
        return get_idx(seq->private, *pos);
 }
 
 }
 
 static void seq_stop(struct seq_file *s, void *v)
-       __releases(instances_lock)
+       __releases(rcu_bh)
 {
-       read_unlock_bh(&instances_lock);
+       rcu_read_unlock_bh();
 }
 
 static int seq_show(struct seq_file *s, void *v)