From: Jiri Kosina Date: Mon, 12 Mar 2007 13:55:12 +0000 (+0100) Subject: HID: allocate hid_parser in a proper way X-Git-Tag: v2.6.21-rc4~4^2~1 X-Git-Url: http://pilppa.com/gitweb/?a=commitdiff_plain;h=47a80edb1d80ae644ea374a016c8e68d43d2671f;p=linux-2.6-omap-h63xx.git HID: allocate hid_parser in a proper way hid_parser is non-trivially large structure, so it should be allocated using vmalloc() to avoid unsuccessful allocations when memory fragmentation is too high. This structue has a very short life, it's destroyed as soon as the report descriptor has been completely parsed. This should be considered a temporary solution, until the hid_parser is rewritten to consume less memory during report descriptor parsing. Acked-by: Mariusz Kozlowski Signed-off-by: Jiri Kosina --- diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index f4ee1afe488..e5894a75a6f 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -654,12 +655,13 @@ struct hid_device *hid_parse_report(__u8 *start, unsigned size) memcpy(device->rdesc, start, size); device->rsize = size; - if (!(parser = kzalloc(sizeof(struct hid_parser), GFP_KERNEL))) { + if (!(parser = vmalloc(sizeof(struct hid_parser)))) { kfree(device->rdesc); kfree(device->collection); kfree(device); return NULL; } + memset(parser, 0, sizeof(struct hid_parser)); parser->device = device; end = start + size; @@ -668,7 +670,7 @@ struct hid_device *hid_parse_report(__u8 *start, unsigned size) if (item.format != HID_ITEM_FORMAT_SHORT) { dbg("unexpected long global item"); hid_free_device(device); - kfree(parser); + vfree(parser); return NULL; } @@ -676,7 +678,7 @@ struct hid_device *hid_parse_report(__u8 *start, unsigned size) dbg("item %u %u %u %u parsing failed\n", item.format, (unsigned)item.size, (unsigned)item.type, (unsigned)item.tag); hid_free_device(device); - kfree(parser); + vfree(parser); return NULL; } @@ -684,23 +686,23 @@ struct hid_device *hid_parse_report(__u8 *start, unsigned size) if (parser->collection_stack_ptr) { dbg("unbalanced collection at end of report description"); hid_free_device(device); - kfree(parser); + vfree(parser); return NULL; } if (parser->local.delimiter_depth) { dbg("unbalanced delimiter at end of report description"); hid_free_device(device); - kfree(parser); + vfree(parser); return NULL; } - kfree(parser); + vfree(parser); return device; } } dbg("item fetching failed at offset %d\n", (int)(end - start)); hid_free_device(device); - kfree(parser); + vfree(parser); return NULL; } EXPORT_SYMBOL_GPL(hid_parse_report);