.. | .. |
---|
2 | 2 | /* Copyright (c) 2016-2018 Mellanox Technologies. All rights reserved */ |
---|
3 | 3 | |
---|
4 | 4 | #include <linux/kernel.h> |
---|
| 5 | +#include <linux/mutex.h> |
---|
5 | 6 | #include <linux/slab.h> |
---|
6 | 7 | |
---|
7 | 8 | #include "spectrum.h" |
---|
8 | 9 | |
---|
9 | 10 | struct mlxsw_sp_kvdl { |
---|
10 | 11 | const struct mlxsw_sp_kvdl_ops *kvdl_ops; |
---|
11 | | - unsigned long priv[0]; |
---|
| 12 | + struct mutex kvdl_lock; /* Protects kvdl allocations */ |
---|
| 13 | + unsigned long priv[]; |
---|
12 | 14 | /* priv has to be always the last item */ |
---|
13 | 15 | }; |
---|
14 | 16 | |
---|
.. | .. |
---|
22 | 24 | GFP_KERNEL); |
---|
23 | 25 | if (!kvdl) |
---|
24 | 26 | return -ENOMEM; |
---|
| 27 | + mutex_init(&kvdl->kvdl_lock); |
---|
25 | 28 | kvdl->kvdl_ops = kvdl_ops; |
---|
26 | 29 | mlxsw_sp->kvdl = kvdl; |
---|
27 | 30 | |
---|
.. | .. |
---|
31 | 34 | return 0; |
---|
32 | 35 | |
---|
33 | 36 | err_init: |
---|
| 37 | + mutex_destroy(&kvdl->kvdl_lock); |
---|
34 | 38 | kfree(kvdl); |
---|
35 | 39 | return err; |
---|
36 | 40 | } |
---|
.. | .. |
---|
40 | 44 | struct mlxsw_sp_kvdl *kvdl = mlxsw_sp->kvdl; |
---|
41 | 45 | |
---|
42 | 46 | kvdl->kvdl_ops->fini(mlxsw_sp, kvdl->priv); |
---|
| 47 | + mutex_destroy(&kvdl->kvdl_lock); |
---|
43 | 48 | kfree(kvdl); |
---|
44 | 49 | } |
---|
45 | 50 | |
---|
.. | .. |
---|
48 | 53 | unsigned int entry_count, u32 *p_entry_index) |
---|
49 | 54 | { |
---|
50 | 55 | struct mlxsw_sp_kvdl *kvdl = mlxsw_sp->kvdl; |
---|
| 56 | + int err; |
---|
51 | 57 | |
---|
52 | | - return kvdl->kvdl_ops->alloc(mlxsw_sp, kvdl->priv, type, |
---|
53 | | - entry_count, p_entry_index); |
---|
| 58 | + mutex_lock(&kvdl->kvdl_lock); |
---|
| 59 | + err = kvdl->kvdl_ops->alloc(mlxsw_sp, kvdl->priv, type, |
---|
| 60 | + entry_count, p_entry_index); |
---|
| 61 | + mutex_unlock(&kvdl->kvdl_lock); |
---|
| 62 | + |
---|
| 63 | + return err; |
---|
54 | 64 | } |
---|
55 | 65 | |
---|
56 | 66 | void mlxsw_sp_kvdl_free(struct mlxsw_sp *mlxsw_sp, |
---|
.. | .. |
---|
59 | 69 | { |
---|
60 | 70 | struct mlxsw_sp_kvdl *kvdl = mlxsw_sp->kvdl; |
---|
61 | 71 | |
---|
| 72 | + mutex_lock(&kvdl->kvdl_lock); |
---|
62 | 73 | kvdl->kvdl_ops->free(mlxsw_sp, kvdl->priv, type, |
---|
63 | 74 | entry_count, entry_index); |
---|
| 75 | + mutex_unlock(&kvdl->kvdl_lock); |
---|
64 | 76 | } |
---|
65 | 77 | |
---|
66 | 78 | int mlxsw_sp_kvdl_alloc_count_query(struct mlxsw_sp *mlxsw_sp, |
---|