static
void pid_tracker_del_node_rcu(struct lttng_pid_hash_node *e)
{
	hlist_del_rcu(&e->hlist);
	/*
	 * We choose to use a heavyweight synchronize on removal here,
	 * since removal of a PID from the tracker mask is a rare
	 * operation, and we don't want to use more cache lines than
	 * what we really need when doing the PID lookups, so we don't
	 * want to afford adding a rcu_head field to those pid hash
	 * node.
	 */
	synchronize_trace();
	kfree(e);
}
Beispiel #2
0
/**
 *	lttng_ioctl - lttng syscall through ioctl
 *
 *	@file: the file
 *	@cmd: the command
 *	@arg: command arg
 *
 *	This ioctl implements lttng commands:
 *	LTTNG_KERNEL_SESSION
 *		Returns a LTTng trace session file descriptor
 *	LTTNG_KERNEL_TRACER_VERSION
 *		Returns the LTTng kernel tracer version
 *	LTTNG_KERNEL_TRACEPOINT_LIST
 *		Returns a file descriptor listing available tracepoints
 *	LTTNG_KERNEL_WAIT_QUIESCENT
 *		Returns after all previously running probes have completed
 *	LTTNG_KERNEL_TRACER_ABI_VERSION
 *		Returns the LTTng kernel tracer ABI version
 *
 * The returned session will be deleted when its file descriptor is closed.
 */
static
long lttng_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
	switch (cmd) {
	case LTTNG_KERNEL_OLD_SESSION:
	case LTTNG_KERNEL_SESSION:
		return lttng_abi_create_session();
	case LTTNG_KERNEL_OLD_TRACER_VERSION:
	{
		struct lttng_kernel_tracer_version v;
		struct lttng_kernel_old_tracer_version oldv;
		struct lttng_kernel_old_tracer_version *uversion =
			(struct lttng_kernel_old_tracer_version __user *) arg;

		lttng_abi_tracer_version(&v);
		oldv.major = v.major;
		oldv.minor = v.minor;
		oldv.patchlevel = v.patchlevel;

		if (copy_to_user(uversion, &oldv, sizeof(oldv)))
			return -EFAULT;
		return 0;
	}
	case LTTNG_KERNEL_TRACER_VERSION:
	{
		struct lttng_kernel_tracer_version version;
		struct lttng_kernel_tracer_version *uversion =
			(struct lttng_kernel_tracer_version __user *) arg;

		lttng_abi_tracer_version(&version);

		if (copy_to_user(uversion, &version, sizeof(version)))
			return -EFAULT;
		return 0;
	}
	case LTTNG_KERNEL_TRACER_ABI_VERSION:
	{
		struct lttng_kernel_tracer_abi_version version;
		struct lttng_kernel_tracer_abi_version *uversion =
			(struct lttng_kernel_tracer_abi_version __user *) arg;

		lttng_abi_tracer_abi_version(&version);

		if (copy_to_user(uversion, &version, sizeof(version)))
			return -EFAULT;
		return 0;
	}
	case LTTNG_KERNEL_OLD_TRACEPOINT_LIST:
	case LTTNG_KERNEL_TRACEPOINT_LIST:
		return lttng_abi_tracepoint_list();
	case LTTNG_KERNEL_SYSCALL_LIST:
		return lttng_abi_syscall_list();
	case LTTNG_KERNEL_OLD_WAIT_QUIESCENT:
	case LTTNG_KERNEL_WAIT_QUIESCENT:
		synchronize_trace();
		return 0;
	case LTTNG_KERNEL_OLD_CALIBRATE:
	{
		struct lttng_kernel_old_calibrate __user *ucalibrate =
			(struct lttng_kernel_old_calibrate __user *) arg;
		struct lttng_kernel_old_calibrate old_calibrate;
		struct lttng_kernel_calibrate calibrate;
		int ret;

		if (copy_from_user(&old_calibrate, ucalibrate, sizeof(old_calibrate)))
			return -EFAULT;
		calibrate.type = old_calibrate.type;
		ret = lttng_calibrate(&calibrate);
		if (copy_to_user(ucalibrate, &old_calibrate, sizeof(old_calibrate)))
			return -EFAULT;
		return ret;
	}
	case LTTNG_KERNEL_CALIBRATE:
	{
		struct lttng_kernel_calibrate __user *ucalibrate =
			(struct lttng_kernel_calibrate __user *) arg;
		struct lttng_kernel_calibrate calibrate;
		int ret;

		if (copy_from_user(&calibrate, ucalibrate, sizeof(calibrate)))
			return -EFAULT;
		ret = lttng_calibrate(&calibrate);
		if (copy_to_user(ucalibrate, &calibrate, sizeof(calibrate)))
			return -EFAULT;
		return ret;
	}
	default:
		return -ENOIOCTLCMD;
	}
}