greybus: embed message buffer into message structure

Embed the buffer for message data into the message structure itself.
This allows us to use a single allocation for each message, and
more importantly will allow us to derive the message structure
describing a message from the buffer itself.

Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
This commit is contained in:
Alex Elder 2014-11-20 16:09:16 -06:00 committed by Greg Kroah-Hartman
parent c08b1ddaeb
commit 87d208feb7
2 changed files with 19 additions and 37 deletions

View File

@ -229,27 +229,6 @@ static void operation_timeout(struct work_struct *work)
gb_operation_complete(operation);
}
static void *
gb_buffer_alloc(struct greybus_host_device *hd, size_t size, gfp_t gfp_flags)
{
u8 *buffer;
buffer = kzalloc(hd->buffer_headroom + size, gfp_flags);
if (buffer)
buffer += hd->buffer_headroom;
return buffer;
}
static void
gb_buffer_free(struct greybus_host_device *hd, void *buffer)
{
u8 *allocated = buffer;
if (allocated)
kfree(allocated - hd->buffer_headroom);
}
/*
* Allocate a message to be used for an operation request or
* response. For outgoing messages, both types of message contain a
@ -257,46 +236,47 @@ gb_buffer_free(struct greybus_host_device *hd, void *buffer)
* responses also contain the same header, but there's no need to
* initialize it here (it'll be overwritten by the incoming
* message).
*
* Our message structure consists of:
* message structure
* headroom
* message header \_ these combined are
* message payload / the message size
*/
static struct gb_message *
gb_operation_message_alloc(struct greybus_host_device *hd, u8 type,
size_t size, gfp_t gfp_flags)
size_t payload_size, gfp_t gfp_flags)
{
struct gb_message *message;
struct gb_operation_msg_hdr *header;
size_t message_size = payload_size + sizeof(*header);
size_t size;
u8 *buffer;
size += sizeof(*header);
if (size > hd->buffer_size_max)
if (message_size > hd->buffer_size_max)
return NULL;
message = kzalloc(sizeof(*message), gfp_flags);
size = sizeof(*message) + hd->buffer_headroom + message_size;
message = kzalloc(size, gfp_flags);
if (!message)
return NULL;
header = gb_buffer_alloc(hd, size, gfp_flags);
if (!header) {
kfree(message);
return NULL;
}
buffer = &message->buffer[0];
header = (struct gb_operation_msg_hdr *)(buffer + hd->buffer_headroom);
/* Fill in the header structure */
header->size = cpu_to_le16(size);
header->size = cpu_to_le16(message_size);
header->operation_id = 0; /* Filled in when submitted */
header->type = type;
message->header = header;
message->payload = header + 1;
message->size = size;
message->size = message_size;
return message;
}
static void gb_operation_message_free(struct gb_message *message)
{
struct greybus_host_device *hd;
hd = message->operation->connection->hd;
gb_buffer_free(hd, message->header);
kfree(message);
}

View File

@ -31,6 +31,8 @@ struct gb_message {
struct gb_operation *operation;
void *cookie;
u8 buffer[];
};
/*