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); }
/** * 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; } }