Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ALSA: firewire: use managed-resource of fw unit device for private data

At present, private data of each driver in ALSA firewire stack is
allocated/freed by kernel slab allocator for corresponding unit on
IEEE 1394 bus. In this case, resource-managed slab allocator is
available to release memory object automatically just before releasing
device structure for the unit. This idea can prevent runtime from
memory leak due to programming mistakes.

This commit uses the allocator for the private data. These drivers
already use reference counter to maintain lifetime of device structure
for the unit by a pair of fw_unit_get()/fw_unit_put(). The private data
is safely released in a callback of 'struct snd_card.private_free().

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>

authored by

Takashi Sakamoto and committed by
Takashi Iwai
366a20d7 4a9a72e0

+29 -48
+6 -7
sound/firewire/bebob/bebob.c
··· 129 129 static void bebob_free(struct snd_bebob *bebob) 130 130 { 131 131 snd_bebob_stream_destroy_duplex(bebob); 132 - fw_unit_put(bebob->unit); 133 132 134 133 kfree(bebob->maudio_special_quirk); 135 134 136 135 mutex_destroy(&bebob->mutex); 137 - kfree(bebob); 136 + fw_unit_put(bebob->unit); 138 137 } 139 138 140 139 /* ··· 294 295 } 295 296 296 297 /* Allocate this independent of sound card instance. */ 297 - bebob = kzalloc(sizeof(struct snd_bebob), GFP_KERNEL); 298 - if (bebob == NULL) 298 + bebob = devm_kzalloc(&unit->device, sizeof(struct snd_bebob), 299 + GFP_KERNEL); 300 + if (!bebob) 299 301 return -ENOMEM; 300 - 301 302 bebob->unit = fw_unit_get(unit); 302 - bebob->entry = entry; 303 - bebob->spec = spec; 304 303 dev_set_drvdata(&unit->device, bebob); 305 304 305 + bebob->entry = entry; 306 + bebob->spec = spec; 306 307 mutex_init(&bebob->mutex); 307 308 spin_lock_init(&bebob->lock); 308 309 init_waitqueue_head(&bebob->hwdep_wait);
+3 -5
sound/firewire/dice/dice.c
··· 126 126 { 127 127 snd_dice_stream_destroy_duplex(dice); 128 128 snd_dice_transaction_destroy(dice); 129 - fw_unit_put(dice->unit); 130 129 131 130 mutex_destroy(&dice->mutex); 132 - kfree(dice); 131 + fw_unit_put(dice->unit); 133 132 } 134 133 135 134 /* ··· 222 223 } 223 224 224 225 /* Allocate this independent of sound card instance. */ 225 - dice = kzalloc(sizeof(struct snd_dice), GFP_KERNEL); 226 - if (dice == NULL) 226 + dice = devm_kzalloc(&unit->device, sizeof(struct snd_dice), GFP_KERNEL); 227 + if (!dice) 227 228 return -ENOMEM; 228 - 229 229 dice->unit = fw_unit_get(unit); 230 230 dev_set_drvdata(&unit->device, dice); 231 231
+4 -5
sound/firewire/digi00x/digi00x.c
··· 46 46 snd_dg00x_stream_destroy_duplex(dg00x); 47 47 snd_dg00x_transaction_unregister(dg00x); 48 48 49 - fw_unit_put(dg00x->unit); 50 - 51 49 mutex_destroy(&dg00x->mutex); 52 - kfree(dg00x); 50 + fw_unit_put(dg00x->unit); 53 51 } 54 52 55 53 static void dg00x_card_free(struct snd_card *card) ··· 118 120 struct snd_dg00x *dg00x; 119 121 120 122 /* Allocate this independent of sound card instance. */ 121 - dg00x = kzalloc(sizeof(struct snd_dg00x), GFP_KERNEL); 122 - if (dg00x == NULL) 123 + dg00x = devm_kzalloc(&unit->device, sizeof(struct snd_dg00x), 124 + GFP_KERNEL); 125 + if (!dg00x) 123 126 return -ENOMEM; 124 127 125 128 dg00x->unit = fw_unit_get(unit);
+3 -7
sound/firewire/fireface/ff.c
··· 32 32 snd_ff_stream_destroy_duplex(ff); 33 33 snd_ff_transaction_unregister(ff); 34 34 35 - fw_unit_put(ff->unit); 36 - 37 35 mutex_destroy(&ff->mutex); 38 - kfree(ff); 36 + fw_unit_put(ff->unit); 39 37 } 40 38 41 39 static void ff_card_free(struct snd_card *card) ··· 100 102 { 101 103 struct snd_ff *ff; 102 104 103 - ff = kzalloc(sizeof(struct snd_ff), GFP_KERNEL); 104 - if (ff == NULL) 105 + ff = devm_kzalloc(&unit->device, sizeof(struct snd_ff), GFP_KERNEL); 106 + if (!ff) 105 107 return -ENOMEM; 106 - 107 - /* initialize myself */ 108 108 ff->unit = fw_unit_get(unit); 109 109 dev_set_drvdata(&unit->device, ff); 110 110
+2 -4
sound/firewire/fireworks/fireworks.c
··· 188 188 { 189 189 snd_efw_stream_destroy_duplex(efw); 190 190 snd_efw_transaction_remove_instance(efw); 191 - fw_unit_put(efw->unit); 192 191 193 192 kfree(efw->resp_buf); 194 193 195 194 mutex_destroy(&efw->mutex); 196 - kfree(efw); 195 + fw_unit_put(efw->unit); 197 196 } 198 197 199 198 /* ··· 311 312 { 312 313 struct snd_efw *efw; 313 314 314 - efw = kzalloc(sizeof(struct snd_efw), GFP_KERNEL); 315 + efw = devm_kzalloc(&unit->device, sizeof(struct snd_efw), GFP_KERNEL); 315 316 if (efw == NULL) 316 317 return -ENOMEM; 317 - 318 318 efw->unit = fw_unit_get(unit); 319 319 dev_set_drvdata(&unit->device, efw); 320 320
+4 -6
sound/firewire/motu/motu.c
··· 57 57 snd_motu_transaction_unregister(motu); 58 58 59 59 snd_motu_stream_destroy_duplex(motu); 60 - fw_unit_put(motu->unit); 61 60 62 61 mutex_destroy(&motu->mutex); 63 - kfree(motu); 62 + fw_unit_put(motu->unit); 64 63 } 65 64 66 65 /* ··· 142 143 struct snd_motu *motu; 143 144 144 145 /* Allocate this independently of sound card instance. */ 145 - motu = kzalloc(sizeof(struct snd_motu), GFP_KERNEL); 146 - if (motu == NULL) 146 + motu = devm_kzalloc(&unit->device, sizeof(struct snd_motu), GFP_KERNEL); 147 + if (!motu) 147 148 return -ENOMEM; 148 - 149 - motu->spec = (const struct snd_motu_spec *)entry->driver_data; 150 149 motu->unit = fw_unit_get(unit); 151 150 dev_set_drvdata(&unit->device, motu); 152 151 152 + motu->spec = (const struct snd_motu_spec *)entry->driver_data; 153 153 mutex_init(&motu->mutex); 154 154 spin_lock_init(&motu->lock); 155 155 init_waitqueue_head(&motu->hwdep_wait);
+4 -7
sound/firewire/oxfw/oxfw.c
··· 121 121 if (oxfw->has_output) 122 122 snd_oxfw_stream_destroy_simplex(oxfw, &oxfw->tx_stream); 123 123 124 - fw_unit_put(oxfw->unit); 125 - 126 124 for (i = 0; i < SND_OXFW_STREAM_FORMAT_ENTRIES; i++) { 127 125 kfree(oxfw->tx_stream_formats[i]); 128 126 kfree(oxfw->rx_stream_formats[i]); ··· 128 130 129 131 kfree(oxfw->spec); 130 132 mutex_destroy(&oxfw->mutex); 131 - kfree(oxfw); 133 + fw_unit_put(oxfw->unit); 132 134 } 133 135 134 136 /* ··· 291 293 return -ENODEV; 292 294 293 295 /* Allocate this independent of sound card instance. */ 294 - oxfw = kzalloc(sizeof(struct snd_oxfw), GFP_KERNEL); 295 - if (oxfw == NULL) 296 + oxfw = devm_kzalloc(&unit->device, sizeof(struct snd_oxfw), GFP_KERNEL); 297 + if (!oxfw) 296 298 return -ENOMEM; 297 - 298 - oxfw->entry = entry; 299 299 oxfw->unit = fw_unit_get(unit); 300 300 dev_set_drvdata(&unit->device, oxfw); 301 301 302 + oxfw->entry = entry; 302 303 mutex_init(&oxfw->mutex); 303 304 spin_lock_init(&oxfw->lock); 304 305 init_waitqueue_head(&oxfw->hwdep_wait);
+3 -7
sound/firewire/tascam/tascam.c
··· 90 90 snd_tscm_transaction_unregister(tscm); 91 91 snd_tscm_stream_destroy_duplex(tscm); 92 92 93 - fw_unit_put(tscm->unit); 94 - 95 93 mutex_destroy(&tscm->mutex); 96 - kfree(tscm); 94 + fw_unit_put(tscm->unit); 97 95 } 98 96 99 97 static void tscm_card_free(struct snd_card *card) ··· 162 164 struct snd_tscm *tscm; 163 165 164 166 /* Allocate this independent of sound card instance. */ 165 - tscm = kzalloc(sizeof(struct snd_tscm), GFP_KERNEL); 166 - if (tscm == NULL) 167 + tscm = devm_kzalloc(&unit->device, sizeof(struct snd_tscm), GFP_KERNEL); 168 + if (!tscm) 167 169 return -ENOMEM; 168 - 169 - /* initialize myself */ 170 170 tscm->unit = fw_unit_get(unit); 171 171 dev_set_drvdata(&unit->device, tscm); 172 172