Commit 84a80f62 authored by Trond Myklebust's avatar Trond Myklebust

NFSv4.1: Convert pNFS deviceid to use kfree_rcu()

Use of synchronize_rcu() when unmounting and potentially freeing a lot
of deviceids is problematic. There really is no reason why we can't just
use kfree_rcu() here.
Signed-off-by: default avatarTrond Myklebust <trond.myklebust@primarydata.com>
parent 2854475f
...@@ -33,7 +33,7 @@ bl_free_deviceid_node(struct nfs4_deviceid_node *d) ...@@ -33,7 +33,7 @@ bl_free_deviceid_node(struct nfs4_deviceid_node *d)
container_of(d, struct pnfs_block_dev, node); container_of(d, struct pnfs_block_dev, node);
bl_free_device(dev); bl_free_device(dev);
kfree(dev); kfree_rcu(dev, node.rcu);
} }
static int static int
......
...@@ -55,7 +55,7 @@ nfs4_fl_free_deviceid(struct nfs4_file_layout_dsaddr *dsaddr) ...@@ -55,7 +55,7 @@ nfs4_fl_free_deviceid(struct nfs4_file_layout_dsaddr *dsaddr)
nfs4_pnfs_ds_put(ds); nfs4_pnfs_ds_put(ds);
} }
kfree(dsaddr->stripe_indices); kfree(dsaddr->stripe_indices);
kfree(dsaddr); kfree_rcu(dsaddr, id_node.rcu);
} }
/* Decode opaque device data and return the result */ /* Decode opaque device data and return the result */
......
...@@ -30,7 +30,7 @@ void nfs4_ff_layout_free_deviceid(struct nfs4_ff_layout_ds *mirror_ds) ...@@ -30,7 +30,7 @@ void nfs4_ff_layout_free_deviceid(struct nfs4_ff_layout_ds *mirror_ds)
{ {
nfs4_print_deviceid(&mirror_ds->id_node.deviceid); nfs4_print_deviceid(&mirror_ds->id_node.deviceid);
nfs4_pnfs_ds_put(mirror_ds->ds); nfs4_pnfs_ds_put(mirror_ds->ds);
kfree(mirror_ds); kfree_rcu(mirror_ds, id_node.rcu);
} }
/* Decode opaque device data and construct new_ds using it */ /* Decode opaque device data and construct new_ds using it */
......
...@@ -57,7 +57,7 @@ objio_free_deviceid_node(struct nfs4_deviceid_node *d) ...@@ -57,7 +57,7 @@ objio_free_deviceid_node(struct nfs4_deviceid_node *d)
dprintk("%s: free od=%p\n", __func__, de->od.od); dprintk("%s: free od=%p\n", __func__, de->od.od);
osduld_put_device(de->od.od); osduld_put_device(de->od.od);
kfree(de); kfree_rcu(d, rcu);
} }
struct objio_segment { struct objio_segment {
......
...@@ -302,6 +302,7 @@ struct nfs4_deviceid_node { ...@@ -302,6 +302,7 @@ struct nfs4_deviceid_node {
unsigned long flags; unsigned long flags;
unsigned long timestamp_unavailable; unsigned long timestamp_unavailable;
struct nfs4_deviceid deviceid; struct nfs4_deviceid deviceid;
struct rcu_head rcu;
atomic_t ref; atomic_t ref;
}; };
......
...@@ -175,8 +175,8 @@ __nfs4_find_get_deviceid(struct nfs_server *server, ...@@ -175,8 +175,8 @@ __nfs4_find_get_deviceid(struct nfs_server *server,
rcu_read_lock(); rcu_read_lock();
d = _lookup_deviceid(server->pnfs_curr_ld, server->nfs_client, id, d = _lookup_deviceid(server->pnfs_curr_ld, server->nfs_client, id,
hash); hash);
if (d != NULL) if (d != NULL && !atomic_inc_not_zero(&d->ref))
atomic_inc(&d->ref); d = NULL;
rcu_read_unlock(); rcu_read_unlock();
return d; return d;
} }
...@@ -236,7 +236,6 @@ nfs4_delete_deviceid(const struct pnfs_layoutdriver_type *ld, ...@@ -236,7 +236,6 @@ nfs4_delete_deviceid(const struct pnfs_layoutdriver_type *ld,
} }
hlist_del_init_rcu(&d->node); hlist_del_init_rcu(&d->node);
spin_unlock(&nfs4_deviceid_lock); spin_unlock(&nfs4_deviceid_lock);
synchronize_rcu();
/* balance the initial ref set in pnfs_insert_deviceid */ /* balance the initial ref set in pnfs_insert_deviceid */
if (atomic_dec_and_test(&d->ref)) if (atomic_dec_and_test(&d->ref))
...@@ -321,7 +320,6 @@ _deviceid_purge_client(const struct nfs_client *clp, long hash) ...@@ -321,7 +320,6 @@ _deviceid_purge_client(const struct nfs_client *clp, long hash)
if (hlist_empty(&tmp)) if (hlist_empty(&tmp))
return; return;
synchronize_rcu();
while (!hlist_empty(&tmp)) { while (!hlist_empty(&tmp)) {
d = hlist_entry(tmp.first, struct nfs4_deviceid_node, tmpnode); d = hlist_entry(tmp.first, struct nfs4_deviceid_node, tmpnode);
hlist_del(&d->tmpnode); hlist_del(&d->tmpnode);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment