diff options
author | Eli Sennesh <esennesh@leaflabs.com> | 2016-05-13 13:27:40 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@google.com> | 2016-05-17 09:21:10 -0700 |
commit | b0e97bce153a416c4de4841078fba57b69de10f5 (patch) | |
tree | 962ded7ebd5df4058211fd709fdcf61395a1c85a /drivers/staging/greybus/operation.c | |
parent | 3a238fc7844f93c799283d8b822178af9638ff0c (diff) | |
download | op-kernel-dev-b0e97bce153a416c4de4841078fba57b69de10f5.zip op-kernel-dev-b0e97bce153a416c4de4841078fba57b69de10f5.tar.gz |
greybus: operation: rate-limit dev_err printing on the receive path
When we receive Greybus operations we don't recognize, requests or responses,
en masse, we can pile up a lot of dev_err() printk messages. Doing so along
the gb_connection_recv() code path can delay receive processing by up to seven
milliseconds, starving the system of bulk-IN urbs. Rate limit those printk
messages, ensuring that after too many repeated errors at the same place in
the code-path, we'll stop printing to the console at all and let the urbs get
returned.
This will help prevent denial-of-service attacks on the AP through the UniPro
network from malicious or malfunctioning modules.
Testing Done: 7 msec recv-to-resubmit-urb processing times go down to <20
usecs
Signed-off-by: Eli Sennesh <esennesh@leaflabs.com>
Reviewed-by: Johan Hovold <johan@hovoldconsulting.com>
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Reviewed-by: Mitchell Tasman <tasman@leaflabs.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Diffstat (limited to 'drivers/staging/greybus/operation.c')
-rw-r--r-- | drivers/staging/greybus/operation.c | 26 |
1 files changed, 14 insertions, 12 deletions
diff --git a/drivers/staging/greybus/operation.c b/drivers/staging/greybus/operation.c index 716627e..31df413 100644 --- a/drivers/staging/greybus/operation.c +++ b/drivers/staging/greybus/operation.c @@ -891,7 +891,7 @@ static void gb_connection_recv_response(struct gb_connection *connection, size_t message_size; if (!operation_id) { - dev_err(&connection->hd->dev, + dev_err_ratelimited(&connection->hd->dev, "%s: invalid response id 0 received\n", connection->name); return; @@ -899,9 +899,9 @@ static void gb_connection_recv_response(struct gb_connection *connection, operation = gb_operation_find_outgoing(connection, operation_id); if (!operation) { - dev_err(&connection->hd->dev, - "%s: unexpected response id 0x%04x received\n", - connection->name, operation_id); + dev_err_ratelimited(&connection->hd->dev, + "%s: unexpected response id 0x%04x received\n", + connection->name, operation_id); return; } @@ -909,7 +909,7 @@ static void gb_connection_recv_response(struct gb_connection *connection, header = message->header; message_size = sizeof(*header) + message->payload_size; if (!errno && size > message_size) { - dev_err(&connection->hd->dev, + dev_err_ratelimited(&connection->hd->dev, "%s: malformed response 0x%02x received (%zu > %zu)\n", connection->name, header->type, size, message_size); @@ -918,7 +918,7 @@ static void gb_connection_recv_response(struct gb_connection *connection, if (gb_operation_short_response_allowed(operation)) { message->payload_size = size - sizeof(*header); } else { - dev_err(&connection->hd->dev, + dev_err_ratelimited(&connection->hd->dev, "%s: short response 0x%02x received (%zu < %zu)\n", connection->name, header->type, size, message_size); @@ -956,13 +956,14 @@ void gb_connection_recv(struct gb_connection *connection, if ((connection->state != GB_CONNECTION_STATE_ENABLED && connection->state != GB_CONNECTION_STATE_ENABLED_TX) || gb_connection_is_offloaded(connection)) { - dev_warn(dev, "%s: dropping %zu received bytes\n", + dev_warn_ratelimited(dev, "%s: dropping %zu received bytes\n", connection->name, size); return; } if (size < sizeof(header)) { - dev_err(dev, "%s: short message received\n", connection->name); + dev_err_ratelimited(dev, "%s: short message received\n", + connection->name); return; } @@ -970,10 +971,11 @@ void gb_connection_recv(struct gb_connection *connection, memcpy(&header, data, sizeof(header)); msg_size = le16_to_cpu(header.size); if (size < msg_size) { - dev_err(dev, - "%s: incomplete message 0x%04x of type 0x%02x received (%zu < %zu)\n", - connection->name, le16_to_cpu(header.operation_id), - header.type, size, msg_size); + dev_err_ratelimited(dev, + "%s: incomplete message 0x%04x of type 0x%02x received (%zu < %zu)\n", + connection->name, + le16_to_cpu(header.operation_id), + header.type, size, msg_size); return; /* XXX Should still complete operation */ } |