Skip to content

Commit b2c042c

Browse files
committed
xen/scsiback: don't call scsiback_free_translation_entry() under lock
scsiback_free_translation_entry() shouldn't be called under spinlock, as it can sleep. This requires to split removing a translation entry from the v2p list from actually calling kref_put() for the entry. Reported-by: Dan Carpenter <error27@gmail.com> Link: https://lore.kernel.org/lkml/Y+JUIl64UDmdkboh@kadam/ Signed-off-by: Juergen Gross <jgross@suse.com> Reviewed-by: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com> Link: https://lore.kernel.org/r/20230328084602.20729-1-jgross@suse.com Signed-off-by: Juergen Gross <jgross@suse.com>
1 parent fae65ef commit b2c042c

File tree

1 file changed

+14
-13
lines changed

1 file changed

+14
-13
lines changed

drivers/xen/xen-scsiback.c

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1010,12 +1010,6 @@ static int scsiback_add_translation_entry(struct vscsibk_info *info,
10101010
return err;
10111011
}
10121012

1013-
static void __scsiback_del_translation_entry(struct v2p_entry *entry)
1014-
{
1015-
list_del(&entry->l);
1016-
kref_put(&entry->kref, scsiback_free_translation_entry);
1017-
}
1018-
10191013
/*
10201014
Delete the translation entry specified
10211015
*/
@@ -1024,18 +1018,20 @@ static int scsiback_del_translation_entry(struct vscsibk_info *info,
10241018
{
10251019
struct v2p_entry *entry;
10261020
unsigned long flags;
1027-
int ret = 0;
10281021

10291022
spin_lock_irqsave(&info->v2p_lock, flags);
10301023
/* Find out the translation entry specified */
10311024
entry = scsiback_chk_translation_entry(info, v);
10321025
if (entry)
1033-
__scsiback_del_translation_entry(entry);
1034-
else
1035-
ret = -ENOENT;
1026+
list_del(&entry->l);
10361027

10371028
spin_unlock_irqrestore(&info->v2p_lock, flags);
1038-
return ret;
1029+
1030+
if (!entry)
1031+
return -ENOENT;
1032+
1033+
kref_put(&entry->kref, scsiback_free_translation_entry);
1034+
return 0;
10391035
}
10401036

10411037
static void scsiback_do_add_lun(struct vscsibk_info *info, const char *state,
@@ -1239,14 +1235,19 @@ static void scsiback_release_translation_entry(struct vscsibk_info *info)
12391235
{
12401236
struct v2p_entry *entry, *tmp;
12411237
struct list_head *head = &(info->v2p_entry_lists);
1238+
struct list_head tmp_list;
12421239
unsigned long flags;
12431240

12441241
spin_lock_irqsave(&info->v2p_lock, flags);
12451242

1246-
list_for_each_entry_safe(entry, tmp, head, l)
1247-
__scsiback_del_translation_entry(entry);
1243+
list_cut_before(&tmp_list, head, head);
12481244

12491245
spin_unlock_irqrestore(&info->v2p_lock, flags);
1246+
1247+
list_for_each_entry_safe(entry, tmp, &tmp_list, l) {
1248+
list_del(&entry->l);
1249+
kref_put(&entry->kref, scsiback_free_translation_entry);
1250+
}
12501251
}
12511252

12521253
static void scsiback_remove(struct xenbus_device *dev)

0 commit comments

Comments
 (0)