mirror of
https://github.com/torvalds/linux
synced 2024-11-05 18:23:50 +00:00
MMC core:
- Use kref to fix KASAN splats triggered during card removal - Don't allocate IDA for OF aliases -----BEGIN PGP SIGNATURE----- iQJLBAABCgA1FiEEugLDXPmKSktSkQsV/iaEJXNYjCkFAmD5RKYXHHVsZi5oYW5z c29uQGxpbmFyby5vcmcACgkQ/iaEJXNYjCkQHQ//d/PYeLJYro8w2LOMm1IlSrSX req6BKidJttTlrgjv5Hc47bDAMFMbmOgiy5u5BixizhCpibJfF4prjUatQMtmXuH I5IgpFruweu+5EuB0QdYHV9rqiXAstZaQWmJF9OPFw+JsDxoSK+4U8efz23K4NN6 s5OVtvUuOeY3/gMlPLpJJuAGKca6nxXVEfCHIm0Dw7IsYC7pGdCzEio6LyhZr9Ar 8Ih6Tmpuj0OrxS+aPBnQUBA65sfiR+4Oak8i7hulDycyiMr9o6iLhFSp97KlIW/o gmsU1FD/JU69lpNPbRSrPD1t26NnZuP6YiCnpw+qCEogDpjiWRoq8mc5X6617mQo G5UilfoyoLTKg6paKgLGXFdNkkGBHWzQdiGVqLawbtNbuMszW+Go0lV9dKqAbI+a IkFzKyggIqTMkGMuD7vYeRTmqc+KgVyPArmT24FsOi4Pz0Lo9rGUZgYFFnQlbxOK JL4GUXPqYYY2bID0SBljfrkoRs7cB+vP5pMkWNwWwDzNcM3qlUTVngGIC9Z8XQn5 PO6xJrZsI5LK2gBaofFg+J7MoJ6XtvkknmIqALynJls9TIFGdJOGCgn5buE23I4D ffm4W7a/+GqxRS+otuoZH1aiIplEF+PTw4vgLmhIwt3gkq1WeAfwqdYwdrwFEXZK 2CNk8B2DbPntDmfyCbE= =17QT -----END PGP SIGNATURE----- Merge tag 'mmc-v5.14-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc Pull MMC fixes from Ulf Hansson: - Use kref to fix KASAN splats triggered during card removal - Don't allocate IDA for OF aliases * tag 'mmc-v5.14-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc: mmc: core: Don't allocate IDA for OF aliases mmc: core: Use kref in place of struct mmc_blk_data::usage
This commit is contained in:
commit
5e09e197a8
2 changed files with 33 additions and 26 deletions
|
@ -28,6 +28,7 @@
|
|||
#include <linux/errno.h>
|
||||
#include <linux/hdreg.h>
|
||||
#include <linux/kdev_t.h>
|
||||
#include <linux/kref.h>
|
||||
#include <linux/blkdev.h>
|
||||
#include <linux/cdev.h>
|
||||
#include <linux/mutex.h>
|
||||
|
@ -111,7 +112,7 @@ struct mmc_blk_data {
|
|||
#define MMC_BLK_CMD23 (1 << 0) /* Can do SET_BLOCK_COUNT for multiblock */
|
||||
#define MMC_BLK_REL_WR (1 << 1) /* MMC Reliable write support */
|
||||
|
||||
unsigned int usage;
|
||||
struct kref kref;
|
||||
unsigned int read_only;
|
||||
unsigned int part_type;
|
||||
unsigned int reset_done;
|
||||
|
@ -181,10 +182,8 @@ static struct mmc_blk_data *mmc_blk_get(struct gendisk *disk)
|
|||
|
||||
mutex_lock(&open_lock);
|
||||
md = disk->private_data;
|
||||
if (md && md->usage == 0)
|
||||
if (md && !kref_get_unless_zero(&md->kref))
|
||||
md = NULL;
|
||||
if (md)
|
||||
md->usage++;
|
||||
mutex_unlock(&open_lock);
|
||||
|
||||
return md;
|
||||
|
@ -196,18 +195,25 @@ static inline int mmc_get_devidx(struct gendisk *disk)
|
|||
return devidx;
|
||||
}
|
||||
|
||||
static void mmc_blk_kref_release(struct kref *ref)
|
||||
{
|
||||
struct mmc_blk_data *md = container_of(ref, struct mmc_blk_data, kref);
|
||||
int devidx;
|
||||
|
||||
devidx = mmc_get_devidx(md->disk);
|
||||
ida_simple_remove(&mmc_blk_ida, devidx);
|
||||
|
||||
mutex_lock(&open_lock);
|
||||
md->disk->private_data = NULL;
|
||||
mutex_unlock(&open_lock);
|
||||
|
||||
put_disk(md->disk);
|
||||
kfree(md);
|
||||
}
|
||||
|
||||
static void mmc_blk_put(struct mmc_blk_data *md)
|
||||
{
|
||||
mutex_lock(&open_lock);
|
||||
md->usage--;
|
||||
if (md->usage == 0) {
|
||||
int devidx = mmc_get_devidx(md->disk);
|
||||
|
||||
ida_simple_remove(&mmc_blk_ida, devidx);
|
||||
put_disk(md->disk);
|
||||
kfree(md);
|
||||
}
|
||||
mutex_unlock(&open_lock);
|
||||
kref_put(&md->kref, mmc_blk_kref_release);
|
||||
}
|
||||
|
||||
static ssize_t power_ro_lock_show(struct device *dev,
|
||||
|
@ -2327,7 +2333,8 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card,
|
|||
|
||||
INIT_LIST_HEAD(&md->part);
|
||||
INIT_LIST_HEAD(&md->rpmbs);
|
||||
md->usage = 1;
|
||||
kref_init(&md->kref);
|
||||
|
||||
md->queue.blkdata = md;
|
||||
|
||||
md->disk->major = MMC_BLOCK_MAJOR;
|
||||
|
|
|
@ -75,7 +75,8 @@ static void mmc_host_classdev_release(struct device *dev)
|
|||
{
|
||||
struct mmc_host *host = cls_dev_to_mmc_host(dev);
|
||||
wakeup_source_unregister(host->ws);
|
||||
ida_simple_remove(&mmc_host_ida, host->index);
|
||||
if (of_alias_get_id(host->parent->of_node, "mmc") < 0)
|
||||
ida_simple_remove(&mmc_host_ida, host->index);
|
||||
kfree(host);
|
||||
}
|
||||
|
||||
|
@ -502,7 +503,7 @@ static int mmc_first_nonreserved_index(void)
|
|||
*/
|
||||
struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
|
||||
{
|
||||
int err;
|
||||
int index;
|
||||
struct mmc_host *host;
|
||||
int alias_id, min_idx, max_idx;
|
||||
|
||||
|
@ -515,20 +516,19 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
|
|||
|
||||
alias_id = of_alias_get_id(dev->of_node, "mmc");
|
||||
if (alias_id >= 0) {
|
||||
min_idx = alias_id;
|
||||
max_idx = alias_id + 1;
|
||||
index = alias_id;
|
||||
} else {
|
||||
min_idx = mmc_first_nonreserved_index();
|
||||
max_idx = 0;
|
||||
|
||||
index = ida_simple_get(&mmc_host_ida, min_idx, max_idx, GFP_KERNEL);
|
||||
if (index < 0) {
|
||||
kfree(host);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
err = ida_simple_get(&mmc_host_ida, min_idx, max_idx, GFP_KERNEL);
|
||||
if (err < 0) {
|
||||
kfree(host);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
host->index = err;
|
||||
host->index = index;
|
||||
|
||||
dev_set_name(&host->class_dev, "mmc%d", host->index);
|
||||
host->ws = wakeup_source_register(NULL, dev_name(&host->class_dev));
|
||||
|
|
Loading…
Reference in a new issue