Re: INFO: rcu detected stall in hub_event

From: Alan Stern
Date: Sun Nov 24 2019 - 11:17:46 EST


Another diagnostic patch.

Alan Stern

#syz test: https://github.com/google/kasan.git 46178223

Index: usb-devel/drivers/hid/hid-core.c
===================================================================
--- usb-devel.orig/drivers/hid/hid-core.c
+++ usb-devel/drivers/hid/hid-core.c
@@ -175,7 +175,8 @@ static int open_collection(struct hid_pa
collection->level = parser->collection_stack_ptr - 1;
collection->parent_idx = (collection->level == 0) ? -1 :
parser->collection_stack[collection->level - 1];
-
+ hid_info(parser->device, "New collection %px: idx %d parent %d type %d\n",
+ collection, (int) collection_index, collection->parent_idx, type);
if (type == HID_COLLECTION_APPLICATION)
parser->device->maxapplication++;

@@ -1046,8 +1047,18 @@ static void hid_apply_multiplier(struct
*/
multiplier_collection = &hid->collection[multiplier->usage->collection_index];
while (multiplier_collection->parent_idx != -1 &&
- multiplier_collection->type != HID_COLLECTION_LOGICAL)
+ multiplier_collection->type != HID_COLLECTION_LOGICAL) {
+ hid_info(hid, "collection %d %px type %d parent %d\n",
+ (int) (multiplier_collection - hid->collection), multiplier_collection,
+ multiplier_collection->type, multiplier_collection->parent_idx);
+ if (multiplier_collection->parent_idx >=
+ multiplier_collection - hid->collection) {
+ hid_info(hid, "BUG: found invalid parent_idx\n");
+ return;
+ }
multiplier_collection = &hid->collection[multiplier_collection->parent_idx];
+ }
+ hid_info(hid, "Got collection\n");

effective_multiplier = hid_calculate_multiplier(hid, multiplier);

@@ -1060,6 +1071,7 @@ static void hid_apply_multiplier(struct
effective_multiplier);
}
}
+ hid_info(hid, "Applied multiplier\n");
}

/*
@@ -1094,16 +1106,23 @@ void hid_setup_resolution_multiplier(str

rep_enum = &hid->report_enum[HID_FEATURE_REPORT];
list_for_each_entry(rep, &rep_enum->report_list, list) {
+ hid_info(hid, "Start report %px maxfield %d\n",
+ rep, rep->maxfield);
for (i = 0; i < rep->maxfield; i++) {
/* Ignore if report count is out of bounds. */
if (rep->field[i]->report_count < 1)
continue;

+ hid_info(hid, "Field %d %px maxusage %d\n",
+ i, rep->field[i], rep->field[i]->maxusage);
for (j = 0; j < rep->field[i]->maxusage; j++) {
usage = &rep->field[i]->usage[j];
- if (usage->hid == HID_GD_RESOLUTION_MULTIPLIER)
+ if (usage->hid == HID_GD_RESOLUTION_MULTIPLIER) {
+ hid_info(hid, "Usage %d %px\n",
+ j, usage);
hid_apply_multiplier(hid,
rep->field[i]);
+ }
}
}
}