.. | .. |
---|
31 | 31 | module_param(max_alloc_per_card, ulong, 0644); |
---|
32 | 32 | MODULE_PARM_DESC(max_alloc_per_card, "Max total allocation bytes per card."); |
---|
33 | 33 | |
---|
| 34 | +static void __update_allocated_size(struct snd_card *card, ssize_t bytes) |
---|
| 35 | +{ |
---|
| 36 | + card->total_pcm_alloc_bytes += bytes; |
---|
| 37 | +} |
---|
| 38 | + |
---|
| 39 | +static void update_allocated_size(struct snd_card *card, ssize_t bytes) |
---|
| 40 | +{ |
---|
| 41 | + mutex_lock(&card->memory_mutex); |
---|
| 42 | + __update_allocated_size(card, bytes); |
---|
| 43 | + mutex_unlock(&card->memory_mutex); |
---|
| 44 | +} |
---|
| 45 | + |
---|
| 46 | +static void decrease_allocated_size(struct snd_card *card, size_t bytes) |
---|
| 47 | +{ |
---|
| 48 | + mutex_lock(&card->memory_mutex); |
---|
| 49 | + WARN_ON(card->total_pcm_alloc_bytes < bytes); |
---|
| 50 | + __update_allocated_size(card, -(ssize_t)bytes); |
---|
| 51 | + mutex_unlock(&card->memory_mutex); |
---|
| 52 | +} |
---|
| 53 | + |
---|
34 | 54 | static int do_alloc_pages(struct snd_card *card, int type, struct device *dev, |
---|
35 | 55 | size_t size, struct snd_dma_buffer *dmab) |
---|
36 | 56 | { |
---|
37 | 57 | int err; |
---|
38 | 58 | |
---|
| 59 | + /* check and reserve the requested size */ |
---|
| 60 | + mutex_lock(&card->memory_mutex); |
---|
39 | 61 | if (max_alloc_per_card && |
---|
40 | | - card->total_pcm_alloc_bytes + size > max_alloc_per_card) |
---|
| 62 | + card->total_pcm_alloc_bytes + size > max_alloc_per_card) { |
---|
| 63 | + mutex_unlock(&card->memory_mutex); |
---|
41 | 64 | return -ENOMEM; |
---|
| 65 | + } |
---|
| 66 | + __update_allocated_size(card, size); |
---|
| 67 | + mutex_unlock(&card->memory_mutex); |
---|
42 | 68 | |
---|
43 | 69 | err = snd_dma_alloc_pages(type, dev, size, dmab); |
---|
44 | 70 | if (!err) { |
---|
45 | | - mutex_lock(&card->memory_mutex); |
---|
46 | | - card->total_pcm_alloc_bytes += dmab->bytes; |
---|
47 | | - mutex_unlock(&card->memory_mutex); |
---|
| 71 | + /* the actual allocation size might be bigger than requested, |
---|
| 72 | + * and we need to correct the account |
---|
| 73 | + */ |
---|
| 74 | + if (dmab->bytes != size) |
---|
| 75 | + update_allocated_size(card, dmab->bytes - size); |
---|
| 76 | + } else { |
---|
| 77 | + /* take back on allocation failure */ |
---|
| 78 | + decrease_allocated_size(card, size); |
---|
48 | 79 | } |
---|
49 | 80 | return err; |
---|
50 | 81 | } |
---|
.. | .. |
---|
53 | 84 | { |
---|
54 | 85 | if (!dmab->area) |
---|
55 | 86 | return; |
---|
56 | | - mutex_lock(&card->memory_mutex); |
---|
57 | | - WARN_ON(card->total_pcm_alloc_bytes < dmab->bytes); |
---|
58 | | - card->total_pcm_alloc_bytes -= dmab->bytes; |
---|
59 | | - mutex_unlock(&card->memory_mutex); |
---|
| 87 | + decrease_allocated_size(card, dmab->bytes); |
---|
60 | 88 | snd_dma_free_pages(dmab); |
---|
61 | 89 | dmab->area = NULL; |
---|
62 | 90 | } |
---|