lkml.org 
[lkml]   [2021]   [Dec]   [13]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v4 06/17] nfs42: use a specific kmem_cache to allocate nfs4_xattr_entry
    Date
    If we want to add the allocated objects to its list_lru, we should use
    kmem_cache_alloc_lru() to allocate objects. So intruduce
    nfs4_xattr_entry_cachep which is used to allocate nfs4_xattr_entry.

    Signed-off-by: Muchun Song <songmuchun@bytedance.com>
    ---
    fs/nfs/nfs42xattr.c | 95 ++++++++++++++++++++++++++---------------------------
    1 file changed, 47 insertions(+), 48 deletions(-)

    diff --git a/fs/nfs/nfs42xattr.c b/fs/nfs/nfs42xattr.c
    index 1c4d2a05b401..5b7af9080db0 100644
    --- a/fs/nfs/nfs42xattr.c
    +++ b/fs/nfs/nfs42xattr.c
    @@ -81,7 +81,7 @@ struct nfs4_xattr_entry {
    struct hlist_node hnode;
    struct list_head lru;
    struct list_head dispose;
    - char *xattr_name;
    + const char *xattr_name;
    void *xattr_value;
    size_t xattr_size;
    struct nfs4_xattr_bucket *bucket;
    @@ -98,6 +98,7 @@ static struct list_lru nfs4_xattr_entry_lru;
    static struct list_lru nfs4_xattr_large_entry_lru;

    static struct kmem_cache *nfs4_xattr_cache_cachep;
    +static struct kmem_cache *nfs4_xattr_entry_cachep;

    /*
    * Hashing helper functions.
    @@ -177,49 +178,27 @@ nfs4_xattr_alloc_entry(const char *name, const void *value,
    {
    struct nfs4_xattr_entry *entry;
    void *valp;
    - char *namep;
    - size_t alloclen, slen;
    - char *buf;
    - uint32_t flags;
    + const char *namep;
    + uint32_t flags = len > PAGE_SIZE ? NFS4_XATTR_ENTRY_EXTVAL : 0;
    + gfp_t gfp = GFP_KERNEL_ACCOUNT | GFP_NOFS;
    + struct list_lru *lru;

    BUILD_BUG_ON(sizeof(struct nfs4_xattr_entry) +
    XATTR_NAME_MAX + 1 > PAGE_SIZE);

    - alloclen = sizeof(struct nfs4_xattr_entry);
    - if (name != NULL) {
    - slen = strlen(name) + 1;
    - alloclen += slen;
    - } else
    - slen = 0;
    -
    - if (alloclen + len <= PAGE_SIZE) {
    - alloclen += len;
    - flags = 0;
    - } else {
    - flags = NFS4_XATTR_ENTRY_EXTVAL;
    - }
    -
    - buf = kmalloc(alloclen, GFP_KERNEL_ACCOUNT | GFP_NOFS);
    - if (buf == NULL)
    + lru = flags & NFS4_XATTR_ENTRY_EXTVAL ? &nfs4_xattr_large_entry_lru :
    + &nfs4_xattr_entry_lru;
    + entry = kmem_cache_alloc_lru(nfs4_xattr_entry_cachep, lru, gfp);
    + if (!entry)
    return NULL;
    - entry = (struct nfs4_xattr_entry *)buf;
    -
    - if (name != NULL) {
    - namep = buf + sizeof(struct nfs4_xattr_entry);
    - memcpy(namep, name, slen);
    - } else {
    - namep = NULL;
    - }
    -
    -
    - if (flags & NFS4_XATTR_ENTRY_EXTVAL) {
    - valp = kvmalloc(len, GFP_KERNEL_ACCOUNT | GFP_NOFS);
    - if (valp == NULL) {
    - kfree(buf);
    - return NULL;
    - }
    - } else if (len != 0) {
    - valp = buf + sizeof(struct nfs4_xattr_entry) + slen;
    + namep = kstrdup_const(name, gfp);
    + if (!namep && name)
    + goto free_buf;
    +
    + if (len != 0) {
    + valp = kvmalloc(len, gfp);
    + if (!valp)
    + goto free_name;
    } else
    valp = NULL;

    @@ -232,23 +211,23 @@ nfs4_xattr_alloc_entry(const char *name, const void *value,

    entry->flags = flags;
    entry->xattr_value = valp;
    - kref_init(&entry->ref);
    entry->xattr_name = namep;
    entry->xattr_size = len;
    - entry->bucket = NULL;
    - INIT_LIST_HEAD(&entry->lru);
    - INIT_LIST_HEAD(&entry->dispose);
    - INIT_HLIST_NODE(&entry->hnode);

    return entry;
    +free_name:
    + kfree_const(namep);
    +free_buf:
    + kmem_cache_free(nfs4_xattr_entry_cachep, entry);
    + return NULL;
    }

    static void
    nfs4_xattr_free_entry(struct nfs4_xattr_entry *entry)
    {
    - if (entry->flags & NFS4_XATTR_ENTRY_EXTVAL)
    - kvfree(entry->xattr_value);
    - kfree(entry);
    + kvfree(entry->xattr_value);
    + kfree_const(entry->xattr_name);
    + kmem_cache_free(nfs4_xattr_entry_cachep, entry);
    }

    static void
    @@ -289,7 +268,7 @@ nfs4_xattr_alloc_cache(void)
    {
    struct nfs4_xattr_cache *cache;

    - cache = kmem_cache_alloc(nfs4_xattr_cache_cachep,
    + cache = kmem_cache_alloc_lru(nfs4_xattr_cache_cachep, &nfs4_xattr_cache_lru,
    GFP_KERNEL_ACCOUNT | GFP_NOFS);
    if (cache == NULL)
    return NULL;
    @@ -992,6 +971,17 @@ static void nfs4_xattr_cache_init_once(void *p)
    INIT_LIST_HEAD(&cache->dispose);
    }

    +static void nfs4_xattr_entry_init_once(void *p)
    +{
    + struct nfs4_xattr_entry *entry = p;
    +
    + kref_init(&entry->ref);
    + entry->bucket = NULL;
    + INIT_LIST_HEAD(&entry->lru);
    + INIT_LIST_HEAD(&entry->dispose);
    + INIT_HLIST_NODE(&entry->hnode);
    +}
    +
    int __init nfs4_xattr_cache_init(void)
    {
    int ret = 0;
    @@ -1003,6 +993,13 @@ int __init nfs4_xattr_cache_init(void)
    if (nfs4_xattr_cache_cachep == NULL)
    return -ENOMEM;

    + nfs4_xattr_entry_cachep = kmem_cache_create("nfs4_xattr_entry",
    + sizeof(struct nfs4_xattr_entry), 0,
    + (SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD | SLAB_ACCOUNT),
    + nfs4_xattr_entry_init_once);
    + if (!nfs4_xattr_entry_cachep)
    + goto out5;
    +
    ret = list_lru_init_memcg(&nfs4_xattr_large_entry_lru,
    &nfs4_xattr_large_entry_shrinker);
    if (ret)
    @@ -1040,6 +1037,8 @@ int __init nfs4_xattr_cache_init(void)
    out3:
    list_lru_destroy(&nfs4_xattr_large_entry_lru);
    out4:
    + kmem_cache_destroy(nfs4_xattr_entry_cachep);
    +out5:
    kmem_cache_destroy(nfs4_xattr_cache_cachep);

    return ret;
    --
    2.11.0
    \
     
     \ /
      Last update: 2021-12-13 17:56    [W:2.491 / U:0.168 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site