162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
262306a36Sopenharmony_ci/******************************************************************************
362306a36Sopenharmony_ci*******************************************************************************
462306a36Sopenharmony_ci**
562306a36Sopenharmony_ci**  Copyright (C) Sistina Software, Inc.  1997-2003  All rights reserved.
662306a36Sopenharmony_ci**  Copyright (C) 2004-2007 Red Hat, Inc.  All rights reserved.
762306a36Sopenharmony_ci**
862306a36Sopenharmony_ci**
962306a36Sopenharmony_ci*******************************************************************************
1062306a36Sopenharmony_ci******************************************************************************/
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci#include "dlm_internal.h"
1362306a36Sopenharmony_ci#include "midcomms.h"
1462306a36Sopenharmony_ci#include "lowcomms.h"
1562306a36Sopenharmony_ci#include "config.h"
1662306a36Sopenharmony_ci#include "memory.h"
1762306a36Sopenharmony_ci#include "ast.h"
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_cistatic struct kmem_cache *writequeue_cache;
2062306a36Sopenharmony_cistatic struct kmem_cache *mhandle_cache;
2162306a36Sopenharmony_cistatic struct kmem_cache *msg_cache;
2262306a36Sopenharmony_cistatic struct kmem_cache *lkb_cache;
2362306a36Sopenharmony_cistatic struct kmem_cache *rsb_cache;
2462306a36Sopenharmony_cistatic struct kmem_cache *cb_cache;
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ciint __init dlm_memory_init(void)
2862306a36Sopenharmony_ci{
2962306a36Sopenharmony_ci	writequeue_cache = dlm_lowcomms_writequeue_cache_create();
3062306a36Sopenharmony_ci	if (!writequeue_cache)
3162306a36Sopenharmony_ci		goto out;
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_ci	mhandle_cache = dlm_midcomms_cache_create();
3462306a36Sopenharmony_ci	if (!mhandle_cache)
3562306a36Sopenharmony_ci		goto mhandle;
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_ci	lkb_cache = kmem_cache_create("dlm_lkb", sizeof(struct dlm_lkb),
3862306a36Sopenharmony_ci				__alignof__(struct dlm_lkb), 0, NULL);
3962306a36Sopenharmony_ci	if (!lkb_cache)
4062306a36Sopenharmony_ci		goto lkb;
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_ci	msg_cache = dlm_lowcomms_msg_cache_create();
4362306a36Sopenharmony_ci	if (!msg_cache)
4462306a36Sopenharmony_ci		goto msg;
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_ci	rsb_cache = kmem_cache_create("dlm_rsb", sizeof(struct dlm_rsb),
4762306a36Sopenharmony_ci				__alignof__(struct dlm_rsb), 0, NULL);
4862306a36Sopenharmony_ci	if (!rsb_cache)
4962306a36Sopenharmony_ci		goto rsb;
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_ci	cb_cache = kmem_cache_create("dlm_cb", sizeof(struct dlm_callback),
5262306a36Sopenharmony_ci				     __alignof__(struct dlm_callback), 0,
5362306a36Sopenharmony_ci				     NULL);
5462306a36Sopenharmony_ci	if (!cb_cache)
5562306a36Sopenharmony_ci		goto cb;
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_ci	return 0;
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_cicb:
6062306a36Sopenharmony_ci	kmem_cache_destroy(rsb_cache);
6162306a36Sopenharmony_cirsb:
6262306a36Sopenharmony_ci	kmem_cache_destroy(msg_cache);
6362306a36Sopenharmony_cimsg:
6462306a36Sopenharmony_ci	kmem_cache_destroy(lkb_cache);
6562306a36Sopenharmony_cilkb:
6662306a36Sopenharmony_ci	kmem_cache_destroy(mhandle_cache);
6762306a36Sopenharmony_cimhandle:
6862306a36Sopenharmony_ci	kmem_cache_destroy(writequeue_cache);
6962306a36Sopenharmony_ciout:
7062306a36Sopenharmony_ci	return -ENOMEM;
7162306a36Sopenharmony_ci}
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_civoid dlm_memory_exit(void)
7462306a36Sopenharmony_ci{
7562306a36Sopenharmony_ci	kmem_cache_destroy(writequeue_cache);
7662306a36Sopenharmony_ci	kmem_cache_destroy(mhandle_cache);
7762306a36Sopenharmony_ci	kmem_cache_destroy(msg_cache);
7862306a36Sopenharmony_ci	kmem_cache_destroy(lkb_cache);
7962306a36Sopenharmony_ci	kmem_cache_destroy(rsb_cache);
8062306a36Sopenharmony_ci	kmem_cache_destroy(cb_cache);
8162306a36Sopenharmony_ci}
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_cichar *dlm_allocate_lvb(struct dlm_ls *ls)
8462306a36Sopenharmony_ci{
8562306a36Sopenharmony_ci	char *p;
8662306a36Sopenharmony_ci
8762306a36Sopenharmony_ci	p = kzalloc(ls->ls_lvblen, GFP_NOFS);
8862306a36Sopenharmony_ci	return p;
8962306a36Sopenharmony_ci}
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_civoid dlm_free_lvb(char *p)
9262306a36Sopenharmony_ci{
9362306a36Sopenharmony_ci	kfree(p);
9462306a36Sopenharmony_ci}
9562306a36Sopenharmony_ci
9662306a36Sopenharmony_cistruct dlm_rsb *dlm_allocate_rsb(struct dlm_ls *ls)
9762306a36Sopenharmony_ci{
9862306a36Sopenharmony_ci	struct dlm_rsb *r;
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_ci	r = kmem_cache_zalloc(rsb_cache, GFP_NOFS);
10162306a36Sopenharmony_ci	return r;
10262306a36Sopenharmony_ci}
10362306a36Sopenharmony_ci
10462306a36Sopenharmony_civoid dlm_free_rsb(struct dlm_rsb *r)
10562306a36Sopenharmony_ci{
10662306a36Sopenharmony_ci	if (r->res_lvbptr)
10762306a36Sopenharmony_ci		dlm_free_lvb(r->res_lvbptr);
10862306a36Sopenharmony_ci	kmem_cache_free(rsb_cache, r);
10962306a36Sopenharmony_ci}
11062306a36Sopenharmony_ci
11162306a36Sopenharmony_cistruct dlm_lkb *dlm_allocate_lkb(struct dlm_ls *ls)
11262306a36Sopenharmony_ci{
11362306a36Sopenharmony_ci	struct dlm_lkb *lkb;
11462306a36Sopenharmony_ci
11562306a36Sopenharmony_ci	lkb = kmem_cache_zalloc(lkb_cache, GFP_NOFS);
11662306a36Sopenharmony_ci	return lkb;
11762306a36Sopenharmony_ci}
11862306a36Sopenharmony_ci
11962306a36Sopenharmony_civoid dlm_free_lkb(struct dlm_lkb *lkb)
12062306a36Sopenharmony_ci{
12162306a36Sopenharmony_ci	if (test_bit(DLM_DFL_USER_BIT, &lkb->lkb_dflags)) {
12262306a36Sopenharmony_ci		struct dlm_user_args *ua;
12362306a36Sopenharmony_ci		ua = lkb->lkb_ua;
12462306a36Sopenharmony_ci		if (ua) {
12562306a36Sopenharmony_ci			kfree(ua->lksb.sb_lvbptr);
12662306a36Sopenharmony_ci			kfree(ua);
12762306a36Sopenharmony_ci		}
12862306a36Sopenharmony_ci	}
12962306a36Sopenharmony_ci
13062306a36Sopenharmony_ci	/* drop references if they are set */
13162306a36Sopenharmony_ci	dlm_callback_set_last_ptr(&lkb->lkb_last_cast, NULL);
13262306a36Sopenharmony_ci	dlm_callback_set_last_ptr(&lkb->lkb_last_cb, NULL);
13362306a36Sopenharmony_ci
13462306a36Sopenharmony_ci	kmem_cache_free(lkb_cache, lkb);
13562306a36Sopenharmony_ci}
13662306a36Sopenharmony_ci
13762306a36Sopenharmony_cistruct dlm_mhandle *dlm_allocate_mhandle(gfp_t allocation)
13862306a36Sopenharmony_ci{
13962306a36Sopenharmony_ci	return kmem_cache_alloc(mhandle_cache, allocation);
14062306a36Sopenharmony_ci}
14162306a36Sopenharmony_ci
14262306a36Sopenharmony_civoid dlm_free_mhandle(struct dlm_mhandle *mhandle)
14362306a36Sopenharmony_ci{
14462306a36Sopenharmony_ci	kmem_cache_free(mhandle_cache, mhandle);
14562306a36Sopenharmony_ci}
14662306a36Sopenharmony_ci
14762306a36Sopenharmony_cistruct writequeue_entry *dlm_allocate_writequeue(void)
14862306a36Sopenharmony_ci{
14962306a36Sopenharmony_ci	return kmem_cache_alloc(writequeue_cache, GFP_ATOMIC);
15062306a36Sopenharmony_ci}
15162306a36Sopenharmony_ci
15262306a36Sopenharmony_civoid dlm_free_writequeue(struct writequeue_entry *writequeue)
15362306a36Sopenharmony_ci{
15462306a36Sopenharmony_ci	kmem_cache_free(writequeue_cache, writequeue);
15562306a36Sopenharmony_ci}
15662306a36Sopenharmony_ci
15762306a36Sopenharmony_cistruct dlm_msg *dlm_allocate_msg(gfp_t allocation)
15862306a36Sopenharmony_ci{
15962306a36Sopenharmony_ci	return kmem_cache_alloc(msg_cache, allocation);
16062306a36Sopenharmony_ci}
16162306a36Sopenharmony_ci
16262306a36Sopenharmony_civoid dlm_free_msg(struct dlm_msg *msg)
16362306a36Sopenharmony_ci{
16462306a36Sopenharmony_ci	kmem_cache_free(msg_cache, msg);
16562306a36Sopenharmony_ci}
16662306a36Sopenharmony_ci
16762306a36Sopenharmony_cistruct dlm_callback *dlm_allocate_cb(void)
16862306a36Sopenharmony_ci{
16962306a36Sopenharmony_ci	return kmem_cache_alloc(cb_cache, GFP_ATOMIC);
17062306a36Sopenharmony_ci}
17162306a36Sopenharmony_ci
17262306a36Sopenharmony_civoid dlm_free_cb(struct dlm_callback *cb)
17362306a36Sopenharmony_ci{
17462306a36Sopenharmony_ci	kmem_cache_free(cb_cache, cb);
17562306a36Sopenharmony_ci}
176