/* Use 0 for success, EFOO otherwise. Note: this is the negative of conventional kernel error values because it's not being returned via syscall return mechanisms.  */
static void cn_proc_ack(int err, int rcvd_seq, int rcvd_ack)
/* Use 0 for success, EFOO otherwise. Note: this is the negative of conventional kernel error values because it's not being returned via syscall return mechanisms.  */
static void cn_proc_ack(int err, int rcvd_seq, int rcvd_ack)
{
	struct cn_msg *msg;
	struct proc_event *ev;
	__u8 buffer[CN_PROC_MSG_SIZE];
	struct timespec ts;
	if (atomic_read(&proc_event_num_listeners) < 1)
		return;
	msg = (struct cn_msg*)buffer;
	ev = (struct proc_event*)msg->data;
	msg->seq = rcvd_seq;
	ktime_get_ts(&ts);
	put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns);
	ev->cpu = -1;
	ev->what = PROC_EVENT_NONE;
	ev->event_data.ack.err = err;
	memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id));
	msg->ack = rcvd_ack + 1;
	msg->len = sizeof(*ev);
	cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
}