mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-10 07:00:48 +00:00
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: Trond Myklebust <trond.myklebust@primarydata.com>
This commit is contained in:
parent
2854475f6c
commit
84a80f62f7
@ -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)
|
|||||||
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)
|
|||||||
{
|
{
|
||||||
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)
|
|||||||
|
|
||||||
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 {
|
|||||||
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,
|
|||||||
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,
|
|||||||
}
|
}
|
||||||
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)
|
|||||||
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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user