Skip to content

Commit 8cc45d9

Browse files
Use a kmem_cache for homa_rpc allocation
1 parent d256e88 commit 8cc45d9

5 files changed

Lines changed: 75 additions & 8 deletions

File tree

homa_impl.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,11 @@ struct homa {
138138
*/
139139
struct homa_socktab *socktab;
140140

141+
/**
142+
* @rpc_kmem_cache: Used to allocate homa_rpc structs efficiently.
143+
*/
144+
struct kmem_cache *rpc_kmem_cache;
145+
141146
#ifndef __STRIP__ /* See strip.py */
142147
/**
143148
* @page_pool_mutex: Synchronizes access to any/all of the page_pools

homa_rpc.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ struct homa_rpc *homa_rpc_alloc_client(struct homa_sock *hsk,
3636
struct homa_rpc *crpc;
3737
int err;
3838

39-
crpc = kzalloc(sizeof(*crpc), GFP_KERNEL);
39+
crpc = kmem_cache_zalloc(hsk->homa->rpc_kmem_cache, GFP_KERNEL);
4040
if (unlikely(!crpc)) {
4141
hsk->error_msg = "couldn't allocate memory for client RPC";
4242
return ERR_PTR(-ENOMEM);
@@ -95,7 +95,7 @@ struct homa_rpc *homa_rpc_alloc_client(struct homa_sock *hsk,
9595
error:
9696
if (crpc->peer)
9797
homa_peer_release(crpc->peer);
98-
kfree(crpc);
98+
kmem_cache_free(hsk->homa->rpc_kmem_cache, crpc);
9999
return ERR_PTR(err);
100100
}
101101

@@ -146,7 +146,7 @@ struct homa_rpc *homa_rpc_alloc_server(struct homa_sock *hsk,
146146
}
147147

148148
/* Initialize fields that don't require the socket lock. */
149-
srpc = kzalloc(sizeof(*srpc), GFP_ATOMIC);
149+
srpc = kmem_cache_zalloc(hsk->homa->rpc_kmem_cache, GFP_ATOMIC);
150150
if (!srpc) {
151151
err = -ENOMEM;
152152
goto error;
@@ -209,9 +209,11 @@ struct homa_rpc *homa_rpc_alloc_server(struct homa_sock *hsk,
209209

210210
error:
211211
homa_bucket_unlock(bucket, id);
212-
if (srpc && srpc->peer)
213-
homa_peer_release(srpc->peer);
214-
kfree(srpc);
212+
if (srpc) {
213+
if (srpc->peer)
214+
homa_peer_release(srpc->peer);
215+
kmem_cache_free(hsk->homa->rpc_kmem_cache, srpc);
216+
}
215217
return ERR_PTR(err);
216218
}
217219

@@ -652,7 +654,7 @@ int homa_rpc_reap(struct homa_sock *hsk, bool reap_all)
652654
#endif /* See strip.py */
653655
rpc->state = 0;
654656
rpc->magic = 0;
655-
kfree(rpc);
657+
kmem_cache_free(hsk->homa->rpc_kmem_cache, rpc);
656658
}
657659
homa_sock_wakeup_wmem(hsk);
658660
tt_record4("reaped %d skbs, %d rpcs; %d skbs remain for port %d",

homa_utils.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,13 @@ int homa_init(struct homa *homa)
6565
if (!homa->socktab)
6666
return -ENOMEM;
6767
homa_socktab_init(homa->socktab);
68+
homa->rpc_kmem_cache = kmem_cache_create("homa_rpc",
69+
sizeof(struct homa_rpc),
70+
0, SLAB_HWCACHE_ALIGN, NULL);
71+
if (!homa->rpc_kmem_cache) {
72+
pr_err("Couldn't initialize rpc_kmem_cache\n");
73+
return -ENOMEM;
74+
}
6875
#ifndef __STRIP__ /* See strip.py */
6976
err = homa_skb_init(homa);
7077
if (err) {
@@ -157,6 +164,10 @@ void homa_destroy(struct homa *homa)
157164
homa->peertab = NULL;
158165
}
159166
#ifndef __STRIP__ /* See strip.py */
167+
if (homa->rpc_kmem_cache) {
168+
kmem_cache_destroy(homa->rpc_kmem_cache);
169+
homa->rpc_kmem_cache = NULL;
170+
}
160171

161172
homa_skb_cleanup(homa);
162173
#endif /* See strip.py */

test/mock.c

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ extern void *malloc(size_t size);
2828
#endif
2929
extern void *memcpy(void *dest, const void *src, size_t n);
3030

31+
struct kmem_cache {
32+
unsigned int size;
33+
int num;
34+
};
35+
3136
/* The variables below can be set to non-zero values by unit tests in order
3237
* to simulate error returns from various functions. If bit 0 is set to 1,
3338
* the next call to the function will fail; bit 1 corresponds to the next
@@ -980,6 +985,41 @@ void *__kmalloc_noprof(size_t size, gfp_t flags)
980985
return mock_kmalloc(size, flags);
981986
}
982987

988+
void *kmem_cache_alloc_noprof(struct kmem_cache *cachep, gfp_t flags)
989+
{
990+
void *result = mock_kmalloc(cachep->size, flags);
991+
992+
if (result)
993+
cachep->num++;
994+
return result;
995+
}
996+
997+
struct kmem_cache *__kmem_cache_create_args(const char *name,
998+
unsigned int object_size,
999+
struct kmem_cache_args *args,
1000+
slab_flags_t flags)
1001+
{
1002+
struct kmem_cache *cache;
1003+
1004+
cache = mock_kmalloc(sizeof(*cache), GFP_KERNEL | __GFP_ZERO);
1005+
if (cache)
1006+
cache->size = object_size;
1007+
return cache;
1008+
}
1009+
1010+
void kmem_cache_destroy(struct kmem_cache *cache)
1011+
{
1012+
if (cache->num != 0)
1013+
FAIL(" kmem_cache destroyed with %d live objects", cache->num);
1014+
kfree(cache);
1015+
}
1016+
1017+
void kmem_cache_free(struct kmem_cache *cache, void *objp)
1018+
{
1019+
cache->num--;
1020+
kfree(objp);
1021+
}
1022+
9831023
void kvfree(const void *addr)
9841024
{
9851025
kfree(addr);

test/unit_homa_utils.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,12 +106,21 @@ TEST_F(homa_utils, homa_init__cant_allocate_port_map)
106106
EXPECT_EQ(NULL, homa2.socktab);
107107
homa_destroy(&homa2);
108108
}
109+
TEST_F(homa_utils, homa_init__cant_create_rpc_kmem_cache)
110+
{
111+
struct homa homa2;
112+
113+
mock_kmalloc_errors = 0x40;
114+
EXPECT_EQ(ENOMEM, -homa_init(&homa2));
115+
EXPECT_SUBSTR("Couldn't initialize rpc_kmem_cache", mock_printk_output);
116+
homa_destroy(&homa2);
117+
}
109118
#ifndef __STRIP__ /* See strip.py */
110119
TEST_F(homa_utils, homa_init__homa_skb_init_failure)
111120
{
112121
struct homa homa2;
113122

114-
mock_kmalloc_errors = 0x40;
123+
mock_kmalloc_errors = 0x80;
115124
EXPECT_EQ(ENOMEM, -homa_init(&homa2));
116125
EXPECT_SUBSTR("Couldn't initialize skb management (errno 12)",
117126
mock_printk_output);

0 commit comments

Comments
 (0)