Skip to content

Commit 5e09e19

Browse files
committed
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
2 parents 3d5895c + 10252ba commit 5e09e19

File tree

2 files changed

+31
-24
lines changed

2 files changed

+31
-24
lines changed

drivers/mmc/core/block.c

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include <linux/errno.h>
2929
#include <linux/hdreg.h>
3030
#include <linux/kdev_t.h>
31+
#include <linux/kref.h>
3132
#include <linux/blkdev.h>
3233
#include <linux/cdev.h>
3334
#include <linux/mutex.h>
@@ -111,7 +112,7 @@ struct mmc_blk_data {
111112
#define MMC_BLK_CMD23 (1 << 0) /* Can do SET_BLOCK_COUNT for multiblock */
112113
#define MMC_BLK_REL_WR (1 << 1) /* MMC Reliable write support */
113114

114-
unsigned int usage;
115+
struct kref kref;
115116
unsigned int read_only;
116117
unsigned int part_type;
117118
unsigned int reset_done;
@@ -181,10 +182,8 @@ static struct mmc_blk_data *mmc_blk_get(struct gendisk *disk)
181182

182183
mutex_lock(&open_lock);
183184
md = disk->private_data;
184-
if (md && md->usage == 0)
185+
if (md && !kref_get_unless_zero(&md->kref))
185186
md = NULL;
186-
if (md)
187-
md->usage++;
188187
mutex_unlock(&open_lock);
189188

190189
return md;
@@ -196,18 +195,25 @@ static inline int mmc_get_devidx(struct gendisk *disk)
196195
return devidx;
197196
}
198197

199-
static void mmc_blk_put(struct mmc_blk_data *md)
198+
static void mmc_blk_kref_release(struct kref *ref)
200199
{
201-
mutex_lock(&open_lock);
202-
md->usage--;
203-
if (md->usage == 0) {
204-
int devidx = mmc_get_devidx(md->disk);
200+
struct mmc_blk_data *md = container_of(ref, struct mmc_blk_data, kref);
201+
int devidx;
205202

206-
ida_simple_remove(&mmc_blk_ida, devidx);
207-
put_disk(md->disk);
208-
kfree(md);
209-
}
203+
devidx = mmc_get_devidx(md->disk);
204+
ida_simple_remove(&mmc_blk_ida, devidx);
205+
206+
mutex_lock(&open_lock);
207+
md->disk->private_data = NULL;
210208
mutex_unlock(&open_lock);
209+
210+
put_disk(md->disk);
211+
kfree(md);
212+
}
213+
214+
static void mmc_blk_put(struct mmc_blk_data *md)
215+
{
216+
kref_put(&md->kref, mmc_blk_kref_release);
211217
}
212218

213219
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,
23272333

23282334
INIT_LIST_HEAD(&md->part);
23292335
INIT_LIST_HEAD(&md->rpmbs);
2330-
md->usage = 1;
2336+
kref_init(&md->kref);
2337+
23312338
md->queue.blkdata = md;
23322339

23332340
md->disk->major = MMC_BLOCK_MAJOR;

drivers/mmc/core/host.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,8 @@ static void mmc_host_classdev_release(struct device *dev)
7575
{
7676
struct mmc_host *host = cls_dev_to_mmc_host(dev);
7777
wakeup_source_unregister(host->ws);
78-
ida_simple_remove(&mmc_host_ida, host->index);
78+
if (of_alias_get_id(host->parent->of_node, "mmc") < 0)
79+
ida_simple_remove(&mmc_host_ida, host->index);
7980
kfree(host);
8081
}
8182

@@ -502,7 +503,7 @@ static int mmc_first_nonreserved_index(void)
502503
*/
503504
struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
504505
{
505-
int err;
506+
int index;
506507
struct mmc_host *host;
507508
int alias_id, min_idx, max_idx;
508509

@@ -515,20 +516,19 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
515516

516517
alias_id = of_alias_get_id(dev->of_node, "mmc");
517518
if (alias_id >= 0) {
518-
min_idx = alias_id;
519-
max_idx = alias_id + 1;
519+
index = alias_id;
520520
} else {
521521
min_idx = mmc_first_nonreserved_index();
522522
max_idx = 0;
523-
}
524523

525-
err = ida_simple_get(&mmc_host_ida, min_idx, max_idx, GFP_KERNEL);
526-
if (err < 0) {
527-
kfree(host);
528-
return NULL;
524+
index = ida_simple_get(&mmc_host_ida, min_idx, max_idx, GFP_KERNEL);
525+
if (index < 0) {
526+
kfree(host);
527+
return NULL;
528+
}
529529
}
530530

531-
host->index = err;
531+
host->index = index;
532532

533533
dev_set_name(&host->class_dev, "mmc%d", host->index);
534534
host->ws = wakeup_source_register(NULL, dev_name(&host->class_dev));

0 commit comments

Comments
 (0)