diff options
Diffstat (limited to '0008-tty-n_r3964-don-t-hand-roll-a-reference-count.patch')
-rw-r--r-- | 0008-tty-n_r3964-don-t-hand-roll-a-reference-count.patch | 155 |
1 files changed, 0 insertions, 155 deletions
diff --git a/0008-tty-n_r3964-don-t-hand-roll-a-reference-count.patch b/0008-tty-n_r3964-don-t-hand-roll-a-reference-count.patch deleted file mode 100644 index 883505b548a82d..00000000000000 --- a/0008-tty-n_r3964-don-t-hand-roll-a-reference-count.patch +++ /dev/null @@ -1,155 +0,0 @@ -From 6e885d94ba582aec3e689d94b3b2deb3570a5e06 Mon Sep 17 00:00:00 2001 -From: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -Date: Thu, 24 Jan 2019 16:44:28 +0100 -Subject: [PATCH 08/15] tty: n_r3964: don't hand-roll a reference count - -rx_block_header had a "locks" variable that was trying to be a reference -count on the header. When it would drop to zero, the memory would be -freed. Convert this to be a kref instead to handle the housekeeping for -doing reference counting properly. - -Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> ---- - drivers/tty/n_r3964.c | 61 ++++++++++++++++++++++---------------------------- - 1 file changed, 28 insertions(+), 33 deletions(-) - ---- a/drivers/tty/n_r3964.c -+++ b/drivers/tty/n_r3964.c -@@ -26,6 +26,7 @@ - #include <linux/param.h> - #include <linux/poll.h> - #include <linux/init.h> -+#include <linux/kref.h> - #include <linux/uaccess.h> - #include <uapi/linux/n_r3964.h> - -@@ -131,8 +132,9 @@ struct rx_block_header { - unsigned int length; /* length in chars without header */ - unsigned char *data; /* usually data is located immediately - * behind this struct */ -- unsigned int locks; /* only used in rx_buffer */ - struct list_head node; -+ struct kref kref; -+ struct r3964_info *info; - }; - - /* Header of received block in tx_buf: */ -@@ -200,8 +202,7 @@ static void add_msg(struct r3964_client_ - int error_code, struct rx_block_header *pBlock); - static struct r3964_message *remove_msg(struct r3964_info *pInfo, - struct r3964_client_info *pClient); --static void remove_client_block(struct r3964_info *pInfo, -- struct r3964_client_info *pClient); -+static void remove_client_block(struct r3964_client_info *pClient); - - static int r3964_open(struct tty_struct *tty); - static void r3964_close(struct tty_struct *tty); -@@ -357,28 +358,28 @@ static void add_rx_queue(struct r3964_in - spin_unlock_irqrestore(&pInfo->lock, flags); - } - --static void remove_from_rx_queue(struct r3964_info *pInfo, -- struct rx_block_header *pHeader) -+static void remove_from_rx_queue(struct kref *kref) - { -- struct rx_block_header *pFind, *tmp; -+ struct rx_block_header *header, *find; -+ struct r3964_info *info; - unsigned long flags; - -- if (pHeader == NULL) -- return; -+ header = container_of(kref, struct rx_block_header, kref); -+ info = header->info; - -- spin_lock_irqsave(&pInfo->lock, flags); -- list_for_each_entry_safe(pFind, tmp, &pInfo->rx_blocks, node) { -- if (pFind == pHeader) { -+ spin_lock_irqsave(&info->lock, flags); -+ list_for_each_entry(find, &info->rx_blocks, node) { -+ if (find == header) { - /* Got it. */ -- list_del(&pFind->node); -- pInfo->blocks_in_rx_queue--; -+ list_del(&find->node); -+ info->blocks_in_rx_queue--; - goto exit; - } - } - exit: -- spin_unlock_irqrestore(&pInfo->lock, flags); -+ spin_unlock_irqrestore(&info->lock, flags); - -- kfree(pHeader); -+ kfree(header); - } - - static void put_char(struct r3964_info *pInfo, unsigned char ch) -@@ -540,7 +541,8 @@ static void on_receive_block(struct r396 - - pBlock->length = length; - pBlock->data = ((unsigned char *)pBlock) + sizeof(*pBlock); -- pBlock->locks = 0; -+ pBlock->info = pInfo; -+ kref_init(&pBlock->kref); - INIT_LIST_HEAD(&pBlock->node); - - memcpy(pBlock->data, pInfo->rx_buf, length); -@@ -854,7 +856,7 @@ static int read_telegram(struct r3964_in - if (copy_to_user(buf, block->data, block->length)) - return -EFAULT; - -- remove_client_block(pInfo, pClient); -+ remove_client_block(pClient); - return block->length; - } - -@@ -893,9 +895,9 @@ queue_the_message: - - pClient->msg_count++; - -- if (pBlock != NULL) { -- pBlock->locks++; -- } -+ if (pBlock != NULL) -+ kref_get(&pBlock->kref); -+ - spin_unlock_irqrestore(&pClient->lock, flags); - } else { - if ((pClient->last_msg->msg_id == R3964_MSG_ACK) -@@ -934,7 +936,7 @@ static struct r3964_message *remove_msg( - - pClient->msg_count--; - if (pMsg->block) { -- remove_client_block(pInfo, pClient); -+ remove_client_block(pClient); - pClient->next_block_to_read = pMsg->block; - } - spin_unlock_irqrestore(&pClient->lock, flags); -@@ -942,21 +944,14 @@ static struct r3964_message *remove_msg( - return pMsg; - } - --static void remove_client_block(struct r3964_info *pInfo, -- struct r3964_client_info *pClient) -+static void remove_client_block(struct r3964_client_info *client) - { - struct rx_block_header *block; - -- TRACE_PS("remove_client_block PID %d", pid_nr(pClient->pid)); -- -- block = pClient->next_block_to_read; -- if (block) { -- block->locks--; -- if (block->locks == 0) { -- remove_from_rx_queue(pInfo, block); -- } -- } -- pClient->next_block_to_read = NULL; -+ block = client->next_block_to_read; -+ if (block) -+ kref_put(&block->kref, remove_from_rx_queue); -+ client->next_block_to_read = NULL; - } - - /************************************************************* |