Эх сурвалжийг харах

rpmsg: rpc: maintain a reference device pointer per open fd

The remote processor recovery process includes the deletion and
recreation of an rpmsg-rpc device. The representative rppc_device
structure is retained and reused if there are any open applications
using the exposed character device. The underlying device pointer
for a rppc_device is though deleted and recreated and is asynchronous
to any of the operations on the exposed character device. A reference
to this device pointer is to be maintained therefore for each open
application so that it can be used during regular fops and until the
file descriptor is closed instead of referencing the rppc_device's
dev pointer, which can become NULL at any point due to a recovery
process. The actual memory of the rppc_device's dev pointer deleted
in the driver's .remove() is freed when all the open applications
have closed either gracefully or forcefully. Any new applications
after a recovery will leverage a newly created device pointer.

Signed-off-by: Suman Anna <s-anna@ti.com>
Suman Anna 11 жил өмнө
parent
commit
515add9bf3

+ 3 - 0
drivers/rpmsg/rpmsg_rpc.c

@@ -564,11 +564,13 @@ static int rppc_open(struct inode *inode, struct file *filp)
 	rpc->state = RPPC_STATE_DISCONNECTED;
 	rpc->rppcdev = rppcdev;
 
+	rpc->dev = get_device(rppcdev->dev);
 	chinfo.src = RPMSG_ADDR_ANY;
 	chinfo.dst = RPMSG_ADDR_ANY;
 	rpc->ept = rpmsg_create_ept(rppcdev->rpdev, rppc_cb, rpc, chinfo);
 	if (!rpc->ept) {
 		dev_err(rppcdev->dev, "create ept failed\n");
+		put_device(rpc->dev);
 		kfree(rpc);
 		return -ENOMEM;
 	}
@@ -622,6 +624,7 @@ static int rppc_release(struct inode *inode, struct file *filp)
 	if (list_empty(&rppcdev->instances))
 		dev_dbg(rppcdev->dev, "all instances have been removed!\n");
 
+	put_device(rpc->dev);
 	kfree(rpc);
 	return 0;
 }

+ 2 - 0
drivers/rpmsg/rpmsg_rpc_internal.h

@@ -62,6 +62,7 @@ struct rppc_device {
  * struct rppc_instance - The per-instance data structure (per user)
  * @list: list node
  * @rppcdev: the rppc device (remote server instance) handle
+ * @dev: local device reference pointer of the rppc device
  * @queue: queue of buffers waiting to be read by the user
  * @lock: mutex for protecting instance variables
  * @readq: wait queue of blocked user threads waiting to read data
@@ -82,6 +83,7 @@ struct rppc_device {
 struct rppc_instance {
 	struct list_head list;
 	struct rppc_device *rppcdev;
+	struct device *dev;
 	struct sk_buff_head queue;
 	struct mutex lock; /* instance state variables lock */
 	wait_queue_head_t readq;