.. | .. |
---|
20 | 20 | #include <linux/list.h> |
---|
21 | 21 | #include <linux/module.h> |
---|
22 | 22 | #include <linux/mutex.h> |
---|
| 23 | +#include <linux/locallock.h> |
---|
23 | 24 | #include <linux/percpu.h> |
---|
24 | 25 | #include <linux/slab.h> |
---|
25 | 26 | #include <linux/smp.h> |
---|
.. | .. |
---|
36 | 37 | |
---|
37 | 38 | static DEFINE_MUTEX(ipcomp_resource_mutex); |
---|
38 | 39 | static void * __percpu *ipcomp_scratches; |
---|
| 40 | +static DEFINE_LOCAL_IRQ_LOCK(ipcomp_scratches_lock); |
---|
39 | 41 | static int ipcomp_scratch_users; |
---|
40 | 42 | static LIST_HEAD(ipcomp_tfms_list); |
---|
41 | 43 | |
---|
.. | .. |
---|
45 | 47 | const int plen = skb->len; |
---|
46 | 48 | int dlen = IPCOMP_SCRATCH_SIZE; |
---|
47 | 49 | const u8 *start = skb->data; |
---|
48 | | - const int cpu = get_cpu(); |
---|
49 | | - u8 *scratch = *per_cpu_ptr(ipcomp_scratches, cpu); |
---|
50 | | - struct crypto_comp *tfm = *per_cpu_ptr(ipcd->tfms, cpu); |
---|
51 | | - int err = crypto_comp_decompress(tfm, start, plen, scratch, &dlen); |
---|
52 | | - int len; |
---|
| 50 | + u8 *scratch; |
---|
| 51 | + struct crypto_comp *tfm; |
---|
| 52 | + int err, len; |
---|
53 | 53 | |
---|
| 54 | + local_lock(ipcomp_scratches_lock); |
---|
| 55 | + |
---|
| 56 | + scratch = *this_cpu_ptr(ipcomp_scratches); |
---|
| 57 | + tfm = *this_cpu_ptr(ipcd->tfms); |
---|
| 58 | + err = crypto_comp_decompress(tfm, start, plen, scratch, &dlen); |
---|
54 | 59 | if (err) |
---|
55 | 60 | goto out; |
---|
56 | 61 | |
---|
.. | .. |
---|
103 | 108 | err = 0; |
---|
104 | 109 | |
---|
105 | 110 | out: |
---|
106 | | - put_cpu(); |
---|
| 111 | + local_unlock(ipcomp_scratches_lock); |
---|
107 | 112 | return err; |
---|
108 | 113 | } |
---|
109 | 114 | |
---|
.. | .. |
---|
146 | 151 | int err; |
---|
147 | 152 | |
---|
148 | 153 | local_bh_disable(); |
---|
| 154 | + local_lock(ipcomp_scratches_lock); |
---|
| 155 | + |
---|
149 | 156 | scratch = *this_cpu_ptr(ipcomp_scratches); |
---|
150 | 157 | tfm = *this_cpu_ptr(ipcd->tfms); |
---|
151 | 158 | err = crypto_comp_compress(tfm, start, plen, scratch, &dlen); |
---|
.. | .. |
---|
158 | 165 | } |
---|
159 | 166 | |
---|
160 | 167 | memcpy(start + sizeof(struct ip_comp_hdr), scratch, dlen); |
---|
| 168 | + local_unlock(ipcomp_scratches_lock); |
---|
161 | 169 | local_bh_enable(); |
---|
162 | 170 | |
---|
163 | 171 | pskb_trim(skb, dlen + sizeof(struct ip_comp_hdr)); |
---|
164 | 172 | return 0; |
---|
165 | 173 | |
---|
166 | 174 | out: |
---|
| 175 | + local_unlock(ipcomp_scratches_lock); |
---|
167 | 176 | local_bh_enable(); |
---|
168 | 177 | return err; |
---|
169 | 178 | } |
---|