Skip to content

Commit da86a54

Browse files
bukinrevadot
authored andcommitted
Import drmkpi_slab which is needed by DRM scheduler.
1 parent 3acf6e4 commit da86a54

File tree

2 files changed

+145
-17
lines changed

2 files changed

+145
-17
lines changed

drmkpi/drmkpi_slab.c

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
/*-
2+
* Copyright (c) 2017 Mellanox Technologies, Ltd.
3+
* All rights reserved.
4+
*
5+
* Redistribution and use in source and binary forms, with or without
6+
* modification, are permitted provided that the following conditions
7+
* are met:
8+
* 1. Redistributions of source code must retain the above copyright
9+
* notice unmodified, this list of conditions, and the following
10+
* disclaimer.
11+
* 2. Redistributions in binary form must reproduce the above copyright
12+
* notice, this list of conditions and the following disclaimer in the
13+
* documentation and/or other materials provided with the distribution.
14+
*
15+
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16+
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17+
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18+
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19+
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20+
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21+
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22+
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24+
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25+
*/
26+
27+
#include <sys/cdefs.h>
28+
__FBSDID("$FreeBSD$");
29+
30+
#include <linux/slab.h>
31+
#include <linux/rcupdate.h>
32+
#include <linux/kernel.h>
33+
34+
struct drmkpi_kmem_rcu {
35+
struct rcu_head rcu_head;
36+
struct drmkpi_kmem_cache *cache;
37+
};
38+
39+
#define LINUX_KMEM_TO_RCU(c, m) \
40+
((struct drmkpi_kmem_rcu *)((char *)(m) + \
41+
(c)->cache_size - sizeof(struct drmkpi_kmem_rcu)))
42+
43+
#define LINUX_RCU_TO_KMEM(r) \
44+
((void *)((char *)(r) + sizeof(struct drmkpi_kmem_rcu) - \
45+
(r)->cache->cache_size))
46+
47+
static int
48+
drmkpi_kmem_ctor(void *mem, int size, void *arg, int flags)
49+
{
50+
struct drmkpi_kmem_cache *c = arg;
51+
52+
if (unlikely(c->cache_flags & SLAB_TYPESAFE_BY_RCU)) {
53+
struct drmkpi_kmem_rcu *rcu = LINUX_KMEM_TO_RCU(c, mem);
54+
55+
/* duplicate cache pointer */
56+
rcu->cache = c;
57+
}
58+
59+
/* check for constructor */
60+
if (likely(c->cache_ctor != NULL))
61+
c->cache_ctor(mem);
62+
63+
return (0);
64+
}
65+
66+
static void
67+
drmkpi_kmem_cache_free_rcu_callback(struct rcu_head *head)
68+
{
69+
struct drmkpi_kmem_rcu *rcu =
70+
container_of(head, struct drmkpi_kmem_rcu, rcu_head);
71+
72+
uma_zfree(rcu->cache->cache_zone, LINUX_RCU_TO_KMEM(rcu));
73+
}
74+
75+
struct drmkpi_kmem_cache *
76+
drmkpi_kmem_cache_create(const char *name, size_t size, size_t align,
77+
unsigned flags, drmkpi_kmem_ctor_t *ctor)
78+
{
79+
struct drmkpi_kmem_cache *c;
80+
81+
c = malloc(sizeof(*c), M_DRMKMALLOC, M_WAITOK);
82+
83+
if (flags & SLAB_HWCACHE_ALIGN)
84+
align = UMA_ALIGN_CACHE;
85+
else if (align != 0)
86+
align--;
87+
88+
if (flags & SLAB_TYPESAFE_BY_RCU) {
89+
/* make room for RCU structure */
90+
size = ALIGN(size, sizeof(void *));
91+
size += sizeof(struct drmkpi_kmem_rcu);
92+
93+
/* create cache_zone */
94+
c->cache_zone = uma_zcreate(name, size,
95+
drmkpi_kmem_ctor, NULL, NULL, NULL,
96+
align, UMA_ZONE_ZINIT);
97+
} else {
98+
/* create cache_zone */
99+
c->cache_zone = uma_zcreate(name, size,
100+
ctor ? drmkpi_kmem_ctor : NULL, NULL,
101+
NULL, NULL, align, 0);
102+
}
103+
104+
c->cache_flags = flags;
105+
c->cache_ctor = ctor;
106+
c->cache_size = size;
107+
return (c);
108+
}
109+
110+
void
111+
drmkpi_kmem_cache_free_rcu(struct drmkpi_kmem_cache *c, void *m)
112+
{
113+
struct drmkpi_kmem_rcu *rcu = LINUX_KMEM_TO_RCU(c, m);
114+
115+
call_rcu(&rcu->rcu_head, drmkpi_kmem_cache_free_rcu_callback);
116+
}
117+
118+
void
119+
drmkpi_kmem_cache_destroy(struct drmkpi_kmem_cache *c)
120+
{
121+
if (unlikely(c->cache_flags & SLAB_TYPESAFE_BY_RCU)) {
122+
/* make sure all free callbacks have been called */
123+
rcu_barrier();
124+
}
125+
126+
uma_zdestroy(c->cache_zone);
127+
free(c, M_DRMKMALLOC);
128+
}

drmkpi/include/linux/slab.h

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -62,21 +62,21 @@ MALLOC_DECLARE(M_DRMKMALLOC);
6262
* Prefix some functions with linux_ to avoid namespace conflict
6363
* with the OpenSolaris code in the kernel.
6464
*/
65-
#define kmem_cache linux_kmem_cache
66-
#define kmem_cache_create(...) linux_kmem_cache_create(__VA_ARGS__)
67-
#define kmem_cache_alloc(...) linux_kmem_cache_alloc(__VA_ARGS__)
68-
#define kmem_cache_free(...) linux_kmem_cache_free(__VA_ARGS__)
69-
#define kmem_cache_destroy(...) linux_kmem_cache_destroy(__VA_ARGS__)
65+
#define kmem_cache drmkpi_kmem_cache
66+
#define kmem_cache_create(...) drmkpi_kmem_cache_create(__VA_ARGS__)
67+
#define kmem_cache_alloc(...) drmkpi_kmem_cache_alloc(__VA_ARGS__)
68+
#define kmem_cache_free(...) drmkpi_kmem_cache_free(__VA_ARGS__)
69+
#define kmem_cache_destroy(...) drmkpi_kmem_cache_destroy(__VA_ARGS__)
7070

7171
#define KMEM_CACHE(__struct, flags) \
72-
linux_kmem_cache_create(#__struct, sizeof(struct __struct), \
72+
drmkpi_kmem_cache_create(#__struct, sizeof(struct __struct), \
7373
__alignof(struct __struct), (flags), NULL)
7474

75-
typedef void linux_kmem_ctor_t (void *);
75+
typedef void drmkpi_kmem_ctor_t (void *);
7676

77-
struct linux_kmem_cache {
77+
struct drmkpi_kmem_cache {
7878
uma_zone_t cache_zone;
79-
linux_kmem_ctor_t *cache_ctor;
79+
drmkpi_kmem_ctor_t *cache_ctor;
8080
unsigned cache_flags;
8181
unsigned cache_size;
8282
};
@@ -161,34 +161,34 @@ ksize(const void *ptr)
161161
return (malloc_usable_size(ptr));
162162
}
163163

164-
extern struct linux_kmem_cache *linux_kmem_cache_create(const char *name,
165-
size_t size, size_t align, unsigned flags, linux_kmem_ctor_t *ctor);
164+
extern struct drmkpi_kmem_cache *drmkpi_kmem_cache_create(const char *name,
165+
size_t size, size_t align, unsigned flags, drmkpi_kmem_ctor_t *ctor);
166166

167167
static inline void *
168-
linux_kmem_cache_alloc(struct linux_kmem_cache *c, gfp_t flags)
168+
drmkpi_kmem_cache_alloc(struct drmkpi_kmem_cache *c, gfp_t flags)
169169
{
170170
return (uma_zalloc_arg(c->cache_zone, c,
171171
linux_check_m_flags(flags)));
172172
}
173173

174174
static inline void *
175-
kmem_cache_zalloc(struct linux_kmem_cache *c, gfp_t flags)
175+
kmem_cache_zalloc(struct drmkpi_kmem_cache *c, gfp_t flags)
176176
{
177177
return (uma_zalloc_arg(c->cache_zone, c,
178178
linux_check_m_flags(flags | M_ZERO)));
179179
}
180180

181-
extern void linux_kmem_cache_free_rcu(struct linux_kmem_cache *, void *);
181+
extern void drmkpi_kmem_cache_free_rcu(struct drmkpi_kmem_cache *, void *);
182182

183183
static inline void
184-
linux_kmem_cache_free(struct linux_kmem_cache *c, void *m)
184+
drmkpi_kmem_cache_free(struct drmkpi_kmem_cache *c, void *m)
185185
{
186186
if (unlikely(c->cache_flags & SLAB_TYPESAFE_BY_RCU))
187-
linux_kmem_cache_free_rcu(c, m);
187+
drmkpi_kmem_cache_free_rcu(c, m);
188188
else
189189
uma_zfree(c->cache_zone, m);
190190
}
191191

192-
extern void linux_kmem_cache_destroy(struct linux_kmem_cache *);
192+
extern void drmkpi_kmem_cache_destroy(struct drmkpi_kmem_cache *);
193193

194194
#endif /* __DRMKPI_LINUX_SLAB_H__ */

0 commit comments

Comments
 (0)