[RFC v2 10/35] RPAL: allow service enable/disable

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Since RPAL involves communication between services, and services require
certain preparations (e.g., registering senders/receivers) before
communication, the kernel needs to sense whether a service is ready to
perform RPAL call-related operations.

This patch adds two interfaces: rpal_enable_service() and
rpal_disable_service(). rpal_enable_service() passes necessary information
to the kernel and marks the service as enabled. RPAL only permits
communication between services in the enabled state. rpal_disable_service()
clears the service's enabled state, thereby prohibiting communication
between the service and others via RPAL.

Signed-off-by: Bo Li <libo.gcs85@xxxxxxxxxxxxx>
---
 arch/x86/rpal/internal.h |  2 ++
 arch/x86/rpal/proc.c     |  6 +++++
 arch/x86/rpal/service.c  | 50 ++++++++++++++++++++++++++++++++++++++++
 include/linux/rpal.h     | 18 +++++++++++++++
 4 files changed, 76 insertions(+)

diff --git a/arch/x86/rpal/internal.h b/arch/x86/rpal/internal.h
index 65f2cf4baf8f..769d3bbe5a6b 100644
--- a/arch/x86/rpal/internal.h
+++ b/arch/x86/rpal/internal.h
@@ -17,6 +17,8 @@ extern bool rpal_inited;
 /* service.c */
 int __init rpal_service_init(void);
 void __init rpal_service_exit(void);
+int rpal_enable_service(unsigned long arg);
+int rpal_disable_service(void);
 
 /* mm.c */
 static inline struct rpal_shared_page *
diff --git a/arch/x86/rpal/proc.c b/arch/x86/rpal/proc.c
index 8a1e4a8a2271..acd814f31649 100644
--- a/arch/x86/rpal/proc.c
+++ b/arch/x86/rpal/proc.c
@@ -63,6 +63,12 @@ static long rpal_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 	case RPAL_IOCTL_UNREGISTER_RECEIVER:
 		ret = rpal_unregister_receiver();
 		break;
+	case RPAL_IOCTL_ENABLE_SERVICE:
+		ret = rpal_enable_service(arg);
+		break;
+	case RPAL_IOCTL_DISABLE_SERVICE:
+		ret = rpal_disable_service();
+		break;
 	default:
 		return -EINVAL;
 	}
diff --git a/arch/x86/rpal/service.c b/arch/x86/rpal/service.c
index 42fb719dbb2a..8a7b679bc28b 100644
--- a/arch/x86/rpal/service.c
+++ b/arch/x86/rpal/service.c
@@ -177,6 +177,7 @@ struct rpal_service *rpal_register_service(void)
 	rs->nr_shared_pages = 0;
 	INIT_LIST_HEAD(&rs->shared_pages);
 	atomic_set(&rs->thread_cnt, 0);
+	rs->enabled = false;
 
 	rs->bad_service = false;
 	rs->base = calculate_base_address(rs->id);
@@ -228,6 +229,52 @@ void rpal_unregister_service(struct rpal_service *rs)
 	rpal_put_service(rs);
 }
 
+int rpal_enable_service(unsigned long arg)
+{
+	struct rpal_service *cur = rpal_current_service();
+	struct rpal_service_metadata rsm;
+	int ret = 0;
+
+	if (cur->bad_service) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	ret = copy_from_user(&rsm, (void __user *)arg, sizeof(rsm));
+	if (ret) {
+		ret = -EFAULT;
+		goto out;
+	}
+
+	mutex_lock(&cur->mutex);
+	if (!cur->enabled) {
+		cur->rsm = rsm;
+		cur->enabled = true;
+	}
+	mutex_unlock(&cur->mutex);
+
+out:
+	return ret;
+}
+
+int rpal_disable_service(void)
+{
+	struct rpal_service *cur = rpal_current_service();
+	int ret = 0;
+
+	mutex_lock(&cur->mutex);
+	if (cur->enabled) {
+		cur->enabled = false;
+	} else {
+		ret = -EINVAL;
+		goto unlock_mutex;
+	}
+
+unlock_mutex:
+	mutex_unlock(&cur->mutex);
+	return ret;
+}
+
 void copy_rpal(struct task_struct *p)
 {
 	struct rpal_service *cur = rpal_current_service();
@@ -244,6 +291,9 @@ void exit_rpal(bool group_dead)
 
 	exit_rpal_thread();
 
+	if (group_dead)
+		rpal_disable_service();
+
 	current->rpal_rs = NULL;
 	rpal_put_service(rs);
 
diff --git a/include/linux/rpal.h b/include/linux/rpal.h
index c33425e896af..2e5010602177 100644
--- a/include/linux/rpal.h
+++ b/include/linux/rpal.h
@@ -84,6 +84,14 @@ enum rpal_task_flag_bits {
 	RPAL_RECEIVER_BIT,
 };
 
+/*
+ * user_meta will be sent to other service when requested.
+ */
+struct rpal_service_metadata {
+	unsigned long version;
+	void __user *user_meta;
+};
+
 /*
  * Each RPAL process (a.k.a RPAL service) should have a pointer to
  * struct rpal_service in all its tasks' task_struct.
@@ -125,6 +133,10 @@ struct rpal_service {
 	/* sender/receiver thread count */
 	atomic_t thread_cnt;
 
+	/* service metadata */
+	bool enabled;
+	struct rpal_service_metadata rsm;
+
 	/* delayed service put work */
 	struct delayed_work delayed_put_work;
 
@@ -206,6 +218,8 @@ enum rpal_command_type {
 	RPAL_CMD_UNREGISTER_SENDER,
 	RPAL_CMD_REGISTER_RECEIVER,
 	RPAL_CMD_UNREGISTER_RECEIVER,
+	RPAL_CMD_ENABLE_SERVICE,
+	RPAL_CMD_DISABLE_SERVICE,
 	RPAL_NR_CMD,
 };
 
@@ -226,6 +240,10 @@ enum rpal_command_type {
 	_IOWR(RPAL_IOCTL_MAGIC, RPAL_CMD_REGISTER_RECEIVER, unsigned long)
 #define RPAL_IOCTL_UNREGISTER_RECEIVER \
 	_IO(RPAL_IOCTL_MAGIC, RPAL_CMD_UNREGISTER_RECEIVER)
+#define RPAL_IOCTL_ENABLE_SERVICE \
+	_IOWR(RPAL_IOCTL_MAGIC, RPAL_CMD_ENABLE_SERVICE, unsigned long)
+#define RPAL_IOCTL_DISABLE_SERVICE \
+	_IO(RPAL_IOCTL_MAGIC, RPAL_CMD_DISABLE_SERVICE)
 
 /**
  * @brief get new reference to a rpal service, a corresponding
-- 
2.20.1





[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [NTFS 3]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [NTFS 3]     [Samba]     [Device Mapper]     [CEPH Development]

  Powered by Linux