| .. | .. |
|---|
| 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 | } |
|---|