From patchwork Tue Sep 12 22:02:15 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xabier Marquiegui X-Patchwork-Id: 13382226 X-Patchwork-Delegate: kuba@kernel.org Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3B134A92D for ; Tue, 12 Sep 2023 22:02:29 +0000 (UTC) Received: from mail-wm1-x335.google.com (mail-wm1-x335.google.com [IPv6:2a00:1450:4864:20::335]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3AB1E10D9 for ; Tue, 12 Sep 2023 15:02:28 -0700 (PDT) Received: by mail-wm1-x335.google.com with SMTP id 5b1f17b1804b1-403012f276dso40188355e9.0 for ; Tue, 12 Sep 2023 15:02:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1694556146; x=1695160946; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=/1zXodHUWWoiS3DLQ0Igs7xvxAHmTbQxFZwMtP1FTBU=; b=QBQCe5P2kDyTfSGlrMfoEN6DLc0WAqaOjzzutXNBJkn7jplHI9yOO4wtLpx4Y45Do2 /ngA36KokALiCDlNBI86zDkqPbu5yPtuIgd5r2YmUsVOoWY8LqnLK9kdwCOBSOYkzYPv 2sJEFSEyl9GUW2uuWay9QJR/HypH2GHkJxj+hhWC9ta+5LgOuHm2I0ExxWOjsNOWGT6A vzc6KLq5hqsfjR5VbMQ1Jej4EHsFLo8tTZz4tfwhsboknvodAmSQ/07/735FPREJSJDc 5QRdnoL5BkRK9GjFxMTjcjx4Ud+aHHA1e31sY6hwkPbq2P8Xp2SVKU7k2+C/UHRgIQff be6w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1694556146; x=1695160946; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=/1zXodHUWWoiS3DLQ0Igs7xvxAHmTbQxFZwMtP1FTBU=; b=k3QKzK42V44Cta64nR25TEzDo6KnDuzmKWti/kn3KPzEvp6+f4p0XqEC7OELYHWy3G +dAKvUXRB1ey8RtE3JWRNJzkJ77O4u6P73vT1UB6GfMOZBDjRv09xd1eHyCK2zomzVut B+vQ7alp+8vx45t4V+f1OE4MjZNLgK2BYkgP6ibQjgZMgJ5HEuthSIRLBvIa/X5wBesH p+foXZXKgSblQNe1wM4V1wT4sxKooahJ8mOYLo/wItnUpm1njPtQNKO2f/Z9Dntp4tEa +ge/LrKMRMaORpsenFY2Vzi0L3dnw7F/GkaJxFxfv5Ye7FaIYNRtNuZWve6IMlLjYpnZ WXRg== X-Gm-Message-State: AOJu0Yzv58fYgqIDPisoCa3sDy86Tkp202X4PbYFm9CyT57wW/iG1fcF hUN9HxzFQznv/jyQOjWbvks+OZdxfSSJ8Q== X-Google-Smtp-Source: AGHT+IFU7w/n9NI6qorb7JT1l79urAzjW+2sriQpNPvL6lTJ0ZTsFOTGXNzh8YsDrGvlaFRGyqQkIg== X-Received: by 2002:a05:600c:24d:b0:3fe:795:712a with SMTP id 13-20020a05600c024d00b003fe0795712amr498555wmj.27.1694556146169; Tue, 12 Sep 2023 15:02:26 -0700 (PDT) Received: from xmarquiegui-HP-ZBook-15-G6.internal.ainguraiiot.com (210.212-55-6.static.clientes.euskaltel.es. [212.55.6.210]) by smtp.gmail.com with ESMTPSA id a3-20020adfeec3000000b003196e992567sm13799082wrp.115.2023.09.12.15.02.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 Sep 2023 15:02:25 -0700 (PDT) From: Xabier Marquiegui To: netdev@vger.kernel.org Cc: richardcochran@gmail.com, horms@kernel.org, chrony-dev@chrony.tuxfamily.org, mlichvar@redhat.com, reibax@gmail.com, ntp-lists@mattcorallo.com, shuah@kernel.org, davem@davemloft.net, rrameshbabu@nvidia.com, alex.maftei@amd.com Subject: [PATCH net-next v2 1/3] ptp: Replace timestamp event queue with linked list Date: Wed, 13 Sep 2023 00:02:15 +0200 Message-Id: <20230912220217.2008895-1-reibax@gmail.com> X-Mailer: git-send-email 2.34.1 Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: kuba@kernel.org This is the first of a set of patches to introduce linked lists to the timestamp event queue. The final goal is to be able to have multiple readers for the timestamp queue. On this one we maintain the original feature set, and we just introduce the linked lists to the data structure. Signed-off-by: Xabier Marquiegui Suggested-by: Richard Cochran --- v2: - Style changes to comform to checkpatch strict suggestions v1: https://lore.kernel.org/netdev/20230906104754.1324412-2-reibax@gmail.com/ drivers/ptp/ptp_chardev.c | 16 ++++++++++++++-- drivers/ptp/ptp_clock.c | 30 ++++++++++++++++++++++++++++-- drivers/ptp/ptp_private.h | 4 +++- drivers/ptp/ptp_sysfs.c | 6 +++++- 4 files changed, 50 insertions(+), 6 deletions(-) diff --git a/drivers/ptp/ptp_chardev.c b/drivers/ptp/ptp_chardev.c index 362bf756e6b7..197edf1179f1 100644 --- a/drivers/ptp/ptp_chardev.c +++ b/drivers/ptp/ptp_chardev.c @@ -435,10 +435,16 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg) __poll_t ptp_poll(struct posix_clock *pc, struct file *fp, poll_table *wait) { struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock); + struct timestamp_event_queue *queue; poll_wait(fp, &ptp->tsev_wq, wait); - return queue_cnt(&ptp->tsevq) ? EPOLLIN : 0; + /* Extract only the first element in the queue list + * TODO: Identify the relevant queue + */ + queue = list_entry(&ptp->tsevqs, struct timestamp_event_queue, qlist); + + return queue_cnt(queue) ? EPOLLIN : 0; } #define EXTTS_BUFSIZE (PTP_BUF_TIMESTAMPS * sizeof(struct ptp_extts_event)) @@ -447,12 +453,18 @@ ssize_t ptp_read(struct posix_clock *pc, uint rdflags, char __user *buf, size_t cnt) { struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock); - struct timestamp_event_queue *queue = &ptp->tsevq; + struct timestamp_event_queue *queue; struct ptp_extts_event *event; unsigned long flags; size_t qcnt, i; int result; + /* Extract only the first element in the queue list + * TODO: Identify the relevant queue + */ + queue = list_first_entry(&ptp->tsevqs, struct timestamp_event_queue, + qlist); + if (cnt % sizeof(struct ptp_extts_event) != 0) return -EINVAL; diff --git a/drivers/ptp/ptp_clock.c b/drivers/ptp/ptp_clock.c index 80f74e38c2da..7ac04a282ec5 100644 --- a/drivers/ptp/ptp_clock.c +++ b/drivers/ptp/ptp_clock.c @@ -166,6 +166,18 @@ static struct posix_clock_operations ptp_clock_ops = { .read = ptp_read, }; +static void ptp_clean_queue_list(struct ptp_clock *ptp) +{ + struct timestamp_event_queue *element; + struct list_head *pos; + + list_for_each(pos, &ptp->tsevqs) { + element = list_entry(pos, struct timestamp_event_queue, qlist); + list_del(pos); + kfree(element); + } +} + static void ptp_clock_release(struct device *dev) { struct ptp_clock *ptp = container_of(dev, struct ptp_clock, dev); @@ -175,6 +187,7 @@ static void ptp_clock_release(struct device *dev) mutex_destroy(&ptp->tsevq_mux); mutex_destroy(&ptp->pincfg_mux); mutex_destroy(&ptp->n_vclocks_mux); + ptp_clean_queue_list(ptp); ida_free(&ptp_clocks_map, ptp->index); kfree(ptp); } @@ -206,6 +219,7 @@ struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info, struct device *parent) { struct ptp_clock *ptp; + struct timestamp_event_queue *queue = NULL; int err = 0, index, major = MAJOR(ptp_devt); size_t size; @@ -228,7 +242,13 @@ struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info, ptp->info = info; ptp->devid = MKDEV(major, index); ptp->index = index; - spin_lock_init(&ptp->tsevq.lock); + INIT_LIST_HEAD(&ptp->tsevqs); + queue = kzalloc(sizeof(*queue), GFP_KERNEL); + if (!queue) + goto no_memory_queue; + spin_lock_init(&queue->lock); + list_add_tail(&queue->qlist, &ptp->tsevqs); + /* TODO - Transform or delete this mutex */ mutex_init(&ptp->tsevq_mux); mutex_init(&ptp->pincfg_mux); mutex_init(&ptp->n_vclocks_mux); @@ -333,6 +353,8 @@ struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info, mutex_destroy(&ptp->tsevq_mux); mutex_destroy(&ptp->pincfg_mux); mutex_destroy(&ptp->n_vclocks_mux); + ptp_clean_queue_list(ptp); +no_memory_queue: ida_free(&ptp_clocks_map, index); no_slot: kfree(ptp); @@ -375,6 +397,7 @@ EXPORT_SYMBOL(ptp_clock_unregister); void ptp_clock_event(struct ptp_clock *ptp, struct ptp_clock_event *event) { + struct timestamp_event_queue *tsevq, *tsevq_alt; struct pps_event_time evt; switch (event->type) { @@ -383,7 +406,10 @@ void ptp_clock_event(struct ptp_clock *ptp, struct ptp_clock_event *event) break; case PTP_CLOCK_EXTTS: - enqueue_external_timestamp(&ptp->tsevq, event); + /* Enqueue timestamp on all other queues */ + list_for_each_entry_safe(tsevq, tsevq_alt, &ptp->tsevqs, qlist) { + enqueue_external_timestamp(tsevq, event); + } wake_up_interruptible(&ptp->tsev_wq); break; diff --git a/drivers/ptp/ptp_private.h b/drivers/ptp/ptp_private.h index 75f58fc468a7..314c21c39f6a 100644 --- a/drivers/ptp/ptp_private.h +++ b/drivers/ptp/ptp_private.h @@ -15,6 +15,7 @@ #include #include #include +#include #define PTP_MAX_TIMESTAMPS 128 #define PTP_BUF_TIMESTAMPS 30 @@ -25,6 +26,7 @@ struct timestamp_event_queue { int head; int tail; spinlock_t lock; + struct list_head qlist; }; struct ptp_clock { @@ -35,7 +37,7 @@ struct ptp_clock { int index; /* index into clocks.map */ struct pps_device *pps_source; long dialed_frequency; /* remembers the frequency adjustment */ - struct timestamp_event_queue tsevq; /* simple fifo for time stamps */ + struct list_head tsevqs; /* timestamp fifo list */ struct mutex tsevq_mux; /* one process at a time reading the fifo */ struct mutex pincfg_mux; /* protect concurrent info->pin_config access */ wait_queue_head_t tsev_wq; diff --git a/drivers/ptp/ptp_sysfs.c b/drivers/ptp/ptp_sysfs.c index 6e4d5456a885..2675f383cd0a 100644 --- a/drivers/ptp/ptp_sysfs.c +++ b/drivers/ptp/ptp_sysfs.c @@ -75,12 +75,16 @@ static ssize_t extts_fifo_show(struct device *dev, struct device_attribute *attr, char *page) { struct ptp_clock *ptp = dev_get_drvdata(dev); - struct timestamp_event_queue *queue = &ptp->tsevq; + struct timestamp_event_queue *queue; struct ptp_extts_event event; unsigned long flags; size_t qcnt; int cnt = 0; + /* The sysfs fifo will always draw from the fist queue */ + queue = list_first_entry(&ptp->tsevqs, struct timestamp_event_queue, + qlist); + memset(&event, 0, sizeof(event)); if (mutex_lock_interruptible(&ptp->tsevq_mux)) From patchwork Tue Sep 12 22:02:16 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xabier Marquiegui X-Patchwork-Id: 13382227 X-Patchwork-Delegate: kuba@kernel.org Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5D1E7BA3B for ; Tue, 12 Sep 2023 22:02:31 +0000 (UTC) Received: from mail-wr1-x429.google.com (mail-wr1-x429.google.com [IPv6:2a00:1450:4864:20::429]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A393310D9 for ; Tue, 12 Sep 2023 15:02:30 -0700 (PDT) Received: by mail-wr1-x429.google.com with SMTP id ffacd0b85a97d-31c73c21113so5819239f8f.1 for ; Tue, 12 Sep 2023 15:02:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1694556149; x=1695160949; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=mQbAfRBB70Uen63fGqIske4p1WkaPvdEZdO44yfXDDc=; b=WZUeRbL8N3OgzNvyjtghXeA59uwRe8+5Vxsi7cqaDVcOYal1HR8ozwYhmS2K+9ZBaF fVUAlQw0drk7Ljxkt9/YezIhcKWw7gBG28PDyWUE1nwoSYbG9MmZJJ+x3CZVTdRczcQO C6Doj0B3Ca8Kon2QQ8HnnwyXwQgvj5+cY6TYgzF6HfANG0r21KFyH5xV8hiOAKiwvL5L axmVkXT7eqijkBkEv7Fd+g+0pymYoSOTyCC217PT0J28Jakkx2dJITjsRzzEaREWYv0C DUxwA3hsUW3yup+isaL6SuRShXuDmEp2w7wJl7wy7OKq2X/idcv0M6mfG27u3EFUQ1Sx o0cA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1694556149; x=1695160949; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=mQbAfRBB70Uen63fGqIske4p1WkaPvdEZdO44yfXDDc=; b=ORaUubz1JqBPf3yQvMDmd8lvHq55MYtK1KhE8NSyfJe4bmu/J25IurSX/BMEiaDa5t WZp3GH6pZSJjIlo+tvqPWzUiYKKKqAzKsIxzzq01shN78t2a/jlUXw5F6Pac41iRi6+H HYQj/yy1t3ZqtkXX94K1KjGmjDPmG3sdszyrzYQb2owMIQWozuLvpr3AotEe1MxZYZw4 bLxM1avDPE/dB2yyf1Ww0rhjZ9v7RUXSy+xeGMbxAV8XD6iRfpDaXVUlNqhgRrqKWx1v wgoaVx3RhunrLpVz7XhmXcvRB6fg1F/pQVPO82uS+44gt2UnCGnsqzd5MsJCK5EBQgRs TdFg== X-Gm-Message-State: AOJu0Yxri/7sP47ULOB0hiUAHV7bLvW6aGKB0i0AG1TvoZd8XjHPjlc+ WkIgpt+wtf9Ml9xUrUvQx5gCwJn3ZhTF9Q== X-Google-Smtp-Source: AGHT+IEzzJICC4Kpkfd4S9hSEegx/EZkg6uTlyyHkdAE6cIn142G+OYFbpRw7TavHF2W81X8uvGH/g== X-Received: by 2002:adf:e7cd:0:b0:317:5d3d:c9df with SMTP id e13-20020adfe7cd000000b003175d3dc9dfmr563316wrn.18.1694556148522; Tue, 12 Sep 2023 15:02:28 -0700 (PDT) Received: from xmarquiegui-HP-ZBook-15-G6.internal.ainguraiiot.com (210.212-55-6.static.clientes.euskaltel.es. [212.55.6.210]) by smtp.gmail.com with ESMTPSA id a3-20020adfeec3000000b003196e992567sm13799082wrp.115.2023.09.12.15.02.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 Sep 2023 15:02:28 -0700 (PDT) From: Xabier Marquiegui To: netdev@vger.kernel.org Cc: richardcochran@gmail.com, horms@kernel.org, chrony-dev@chrony.tuxfamily.org, mlichvar@redhat.com, reibax@gmail.com, ntp-lists@mattcorallo.com, shuah@kernel.org, davem@davemloft.net, rrameshbabu@nvidia.com, alex.maftei@amd.com Subject: [PATCH net-next v2 2/3] ptp: support multiple timestamp event readers Date: Wed, 13 Sep 2023 00:02:16 +0200 Message-Id: <20230912220217.2008895-2-reibax@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230912220217.2008895-1-reibax@gmail.com> References: <20230912220217.2008895-1-reibax@gmail.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: kuba@kernel.org Use linked lists to create one event queue per open file. This enables simultaneous readers for timestamp event queues. Signed-off-by: Xabier Marquiegui Suggested-by: Richard Cochran --- v2: - fix ptp_poll() return value - Style changes to comform to checkpatch strict suggestions - more coherent ptp_read error exit routines v1: https://lore.kernel.org/netdev/20230906104754.1324412-3-reibax@gmail.com/ drivers/ptp/ptp_chardev.c | 100 +++++++++++++++++++++++++++++--------- drivers/ptp/ptp_clock.c | 6 +-- drivers/ptp/ptp_private.h | 4 +- drivers/ptp/ptp_sysfs.c | 4 -- 4 files changed, 82 insertions(+), 32 deletions(-) diff --git a/drivers/ptp/ptp_chardev.c b/drivers/ptp/ptp_chardev.c index 197edf1179f1..c9da0f27d204 100644 --- a/drivers/ptp/ptp_chardev.c +++ b/drivers/ptp/ptp_chardev.c @@ -103,9 +103,39 @@ int ptp_set_pinfunc(struct ptp_clock *ptp, unsigned int pin, int ptp_open(struct posix_clock *pc, fmode_t fmode) { + struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock); + struct timestamp_event_queue *queue; + + queue = kzalloc(sizeof(*queue), GFP_KERNEL); + if (!queue) + return -EINVAL; + queue->reader_pid = task_pid_nr(current); + list_add_tail(&queue->qlist, &ptp->tsevqs); + return 0; } +int ptp_release(struct posix_clock *pc) +{ + struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock); + struct list_head *pos, *n; + struct timestamp_event_queue *element; + int found = -1; + pid_t reader_pid = task_pid_nr(current); + + list_for_each_safe(pos, n, &ptp->tsevqs) { + element = list_entry(pos, struct timestamp_event_queue, qlist); + if (element->reader_pid == reader_pid) { + list_del(pos); + kfree(element); + found = 0; + return found; + } + } + + return found; +} + long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg) { struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock); @@ -435,14 +465,24 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg) __poll_t ptp_poll(struct posix_clock *pc, struct file *fp, poll_table *wait) { struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock); + pid_t reader_pid = task_pid_nr(current); struct timestamp_event_queue *queue; + struct list_head *pos, *n; + bool found = false; poll_wait(fp, &ptp->tsev_wq, wait); - /* Extract only the first element in the queue list - * TODO: Identify the relevant queue - */ - queue = list_entry(&ptp->tsevqs, struct timestamp_event_queue, qlist); + /* Extract only the desired element in the queue list */ + list_for_each_safe(pos, n, &ptp->tsevqs) { + queue = list_entry(pos, struct timestamp_event_queue, qlist); + if (queue->reader_pid == reader_pid) { + found = true; + break; + } + } + + if (!found) + return EPOLLERR; return queue_cnt(queue) ? EPOLLIN : 0; } @@ -453,44 +493,54 @@ ssize_t ptp_read(struct posix_clock *pc, uint rdflags, char __user *buf, size_t cnt) { struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock); + pid_t reader_pid = task_pid_nr(current); struct timestamp_event_queue *queue; struct ptp_extts_event *event; + struct list_head *pos, *n; unsigned long flags; + bool found = false; size_t qcnt, i; int result; - /* Extract only the first element in the queue list - * TODO: Identify the relevant queue - */ - queue = list_first_entry(&ptp->tsevqs, struct timestamp_event_queue, - qlist); + /* Extract only the desired element in the queue list */ + list_for_each_safe(pos, n, &ptp->tsevqs) { + queue = list_entry(pos, struct timestamp_event_queue, qlist); + if (queue->reader_pid == reader_pid) { + found = true; + break; + } + } - if (cnt % sizeof(struct ptp_extts_event) != 0) - return -EINVAL; + if (!found) { + result = -EINVAL; + goto exit; + } + + if (cnt % sizeof(struct ptp_extts_event) != 0) { + result = -EINVAL; + goto exit; + } if (cnt > EXTTS_BUFSIZE) cnt = EXTTS_BUFSIZE; cnt = cnt / sizeof(struct ptp_extts_event); - if (mutex_lock_interruptible(&ptp->tsevq_mux)) - return -ERESTARTSYS; - if (wait_event_interruptible(ptp->tsev_wq, ptp->defunct || queue_cnt(queue))) { - mutex_unlock(&ptp->tsevq_mux); - return -ERESTARTSYS; + result = -ERESTARTSYS; + goto exit; } if (ptp->defunct) { - mutex_unlock(&ptp->tsevq_mux); - return -ENODEV; + result = -ENODEV; + goto exit; } event = kmalloc(EXTTS_BUFSIZE, GFP_KERNEL); if (!event) { - mutex_unlock(&ptp->tsevq_mux); - return -ENOMEM; + result = -ENOMEM; + goto exit; } spin_lock_irqsave(&queue->lock, flags); @@ -509,12 +559,16 @@ ssize_t ptp_read(struct posix_clock *pc, cnt = cnt * sizeof(struct ptp_extts_event); - mutex_unlock(&ptp->tsevq_mux); - result = cnt; - if (copy_to_user(buf, event, cnt)) + if (copy_to_user(buf, event, cnt)) { result = -EFAULT; + goto free_event; + } +free_event: kfree(event); +exit: + if (result < 0) + ptp_release(pc); return result; } diff --git a/drivers/ptp/ptp_clock.c b/drivers/ptp/ptp_clock.c index 7ac04a282ec5..d52fc23e20a8 100644 --- a/drivers/ptp/ptp_clock.c +++ b/drivers/ptp/ptp_clock.c @@ -162,6 +162,7 @@ static struct posix_clock_operations ptp_clock_ops = { .clock_settime = ptp_clock_settime, .ioctl = ptp_ioctl, .open = ptp_open, + .release = ptp_release, .poll = ptp_poll, .read = ptp_read, }; @@ -184,7 +185,6 @@ static void ptp_clock_release(struct device *dev) ptp_cleanup_pin_groups(ptp); kfree(ptp->vclock_index); - mutex_destroy(&ptp->tsevq_mux); mutex_destroy(&ptp->pincfg_mux); mutex_destroy(&ptp->n_vclocks_mux); ptp_clean_queue_list(ptp); @@ -246,10 +246,9 @@ struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info, queue = kzalloc(sizeof(*queue), GFP_KERNEL); if (!queue) goto no_memory_queue; + queue->reader_pid = 0; spin_lock_init(&queue->lock); list_add_tail(&queue->qlist, &ptp->tsevqs); - /* TODO - Transform or delete this mutex */ - mutex_init(&ptp->tsevq_mux); mutex_init(&ptp->pincfg_mux); mutex_init(&ptp->n_vclocks_mux); init_waitqueue_head(&ptp->tsev_wq); @@ -350,7 +349,6 @@ struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info, if (ptp->kworker) kthread_destroy_worker(ptp->kworker); kworker_err: - mutex_destroy(&ptp->tsevq_mux); mutex_destroy(&ptp->pincfg_mux); mutex_destroy(&ptp->n_vclocks_mux); ptp_clean_queue_list(ptp); diff --git a/drivers/ptp/ptp_private.h b/drivers/ptp/ptp_private.h index 314c21c39f6a..046d1482bcee 100644 --- a/drivers/ptp/ptp_private.h +++ b/drivers/ptp/ptp_private.h @@ -27,6 +27,7 @@ struct timestamp_event_queue { int tail; spinlock_t lock; struct list_head qlist; + pid_t reader_pid; }; struct ptp_clock { @@ -38,7 +39,6 @@ struct ptp_clock { struct pps_device *pps_source; long dialed_frequency; /* remembers the frequency adjustment */ struct list_head tsevqs; /* timestamp fifo list */ - struct mutex tsevq_mux; /* one process at a time reading the fifo */ struct mutex pincfg_mux; /* protect concurrent info->pin_config access */ wait_queue_head_t tsev_wq; int defunct; /* tells readers to go away when clock is being removed */ @@ -124,6 +124,8 @@ long ptp_ioctl(struct posix_clock *pc, int ptp_open(struct posix_clock *pc, fmode_t fmode); +int ptp_release(struct posix_clock *pc); + ssize_t ptp_read(struct posix_clock *pc, uint flags, char __user *buf, size_t cnt); diff --git a/drivers/ptp/ptp_sysfs.c b/drivers/ptp/ptp_sysfs.c index 2675f383cd0a..512b0164ef18 100644 --- a/drivers/ptp/ptp_sysfs.c +++ b/drivers/ptp/ptp_sysfs.c @@ -87,9 +87,6 @@ static ssize_t extts_fifo_show(struct device *dev, memset(&event, 0, sizeof(event)); - if (mutex_lock_interruptible(&ptp->tsevq_mux)) - return -ERESTARTSYS; - spin_lock_irqsave(&queue->lock, flags); qcnt = queue_cnt(queue); if (qcnt) { @@ -104,7 +101,6 @@ static ssize_t extts_fifo_show(struct device *dev, cnt = snprintf(page, PAGE_SIZE, "%u %lld %u\n", event.index, event.t.sec, event.t.nsec); out: - mutex_unlock(&ptp->tsevq_mux); return cnt; } static DEVICE_ATTR(fifo, 0444, extts_fifo_show, NULL); From patchwork Tue Sep 12 22:02:17 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xabier Marquiegui X-Patchwork-Id: 13382228 X-Patchwork-Delegate: kuba@kernel.org Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4EBF2BA29 for ; Tue, 12 Sep 2023 22:02:34 +0000 (UTC) Received: from mail-wr1-x429.google.com (mail-wr1-x429.google.com [IPv6:2a00:1450:4864:20::429]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 204F810DD for ; Tue, 12 Sep 2023 15:02:33 -0700 (PDT) Received: by mail-wr1-x429.google.com with SMTP id ffacd0b85a97d-31768ce2e81so6257811f8f.1 for ; Tue, 12 Sep 2023 15:02:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1694556151; x=1695160951; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=MRZNSdP60g3qhYw+9NkB+2cckjXOfrOOXxcNI7EXbk8=; b=iPZko5XIRObRyQZ68Z3eupgWycobinUMEn7po1rfZBNwQYqkSW3d8sJfaXSzazlSVA zsy28PpMu+lOrZxbTxouKdJTLNXwpiJfcqAoEMPveXmPXkbDlY0SenJ91yp6MwlYHMN2 lOf7A/iwxihp3/3QWQdsXm0SBbi891ARsywTbkjZZ3uRKG/K+KsE4O/Hofddg5/zJOx8 ZbmOxc+rcvI4vz4vBJys5lzYWVwPpDLokp67fucSGdmRTwSPza3haoWgLosmIrEDNJPK VL/zNWEZ97wbd8z/wk61B8g9vSXgqpkVp2ZzFWB3ST1XI0GDaCcAWcDdzxM4/l6aP/Rl aVeQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1694556151; x=1695160951; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=MRZNSdP60g3qhYw+9NkB+2cckjXOfrOOXxcNI7EXbk8=; b=o8QCII/51K5Z2g1GVAQdOVdTTpCu9fqG5/RAFVds/hSLfDjKQfelM+VTRDw8BMP7df 9flt18NlceGGgm586TUz7/fMgVNty7rDDFWTD4C4QC/p0AY4z12kylXh5Se1v1WXIHmw ixafuN1W4NCvMOA4aNHTi8a7Th6eLDX0WnQXoiZfItaKSU15DnUJhVJDB5KVELACK2T7 AGRZeKSzOrqasK5u0+wfozXEozNvLEH1lKW/iFa/8/1VcjUoh0i1/ew/2ktPJLgLVw8L 52V1vWnvVPbT2smsmC91Z58kTfd5FUTvXfF7xp8/4J2Mfv+s+i+Z05LOtGegR3KWr+Ss szLw== X-Gm-Message-State: AOJu0YxkOPPFqCxmPjrQctiuZRsI4Hz1zrGj2/HHzlW8zGxxFOlOi/KJ KK7p8aDkXgAAuGBBIVQ3je4lQEi8t7QkHA== X-Google-Smtp-Source: AGHT+IGUQwG9R6+WCiIoTcqFACdP9oaRiOb8ZHnGS5T1NURVCtulDTOQ9aDoQ/2+CC+WTfqwgxUbAg== X-Received: by 2002:adf:f98a:0:b0:317:5f04:bc00 with SMTP id f10-20020adff98a000000b003175f04bc00mr597523wrr.27.1694556150940; Tue, 12 Sep 2023 15:02:30 -0700 (PDT) Received: from xmarquiegui-HP-ZBook-15-G6.internal.ainguraiiot.com (210.212-55-6.static.clientes.euskaltel.es. [212.55.6.210]) by smtp.gmail.com with ESMTPSA id a3-20020adfeec3000000b003196e992567sm13799082wrp.115.2023.09.12.15.02.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 Sep 2023 15:02:30 -0700 (PDT) From: Xabier Marquiegui To: netdev@vger.kernel.org Cc: richardcochran@gmail.com, horms@kernel.org, chrony-dev@chrony.tuxfamily.org, mlichvar@redhat.com, reibax@gmail.com, ntp-lists@mattcorallo.com, shuah@kernel.org, davem@davemloft.net, rrameshbabu@nvidia.com, alex.maftei@amd.com Subject: [PATCH net-next v2 3/3] ptp: support event queue reader channel masks Date: Wed, 13 Sep 2023 00:02:17 +0200 Message-Id: <20230912220217.2008895-3-reibax@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230912220217.2008895-1-reibax@gmail.com> References: <20230912220217.2008895-1-reibax@gmail.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: kuba@kernel.org Implement ioctl to support filtering of external timestamp event queue channels per reader based on the process PID accessing the timestamp queue. Can be tested using testptp test binary. Use lsof to figure out readers of the DUT. LSB of the timestamp channel mask is channel 0. eg: To allow PID 3000 to access only ts channel 0: ``` # testptp -F 3000,0x1 ``` eg: To allow PID 3000 to access any channel: ``` # testptp -F 3000,0xFFFFFFFF ``` Signed-off-by: Xabier Marquiegui Suggested-by: Richard Cochran --- v2: - fix testptp compilation error: unknown type name 'pid_t' - rename mask variable for easier code traceability - more detailed commit message with two examples v1: https://lore.kernel.org/netdev/20230906104754.1324412-4-reibax@gmail.com/ drivers/ptp/ptp_chardev.c | 17 +++++++++++++++++ drivers/ptp/ptp_clock.c | 4 +++- drivers/ptp/ptp_private.h | 1 + include/uapi/linux/ptp_clock.h | 7 +++++++ tools/testing/selftests/ptp/testptp.c | 26 +++++++++++++++++++++++++- 5 files changed, 53 insertions(+), 2 deletions(-) diff --git a/drivers/ptp/ptp_chardev.c b/drivers/ptp/ptp_chardev.c index c9da0f27d204..007f7710421e 100644 --- a/drivers/ptp/ptp_chardev.c +++ b/drivers/ptp/ptp_chardev.c @@ -109,6 +109,7 @@ int ptp_open(struct posix_clock *pc, fmode_t fmode) queue = kzalloc(sizeof(*queue), GFP_KERNEL); if (!queue) return -EINVAL; + queue->tsevqmask = 0xFFFFFFFF; queue->reader_pid = task_pid_nr(current); list_add_tail(&queue->qlist, &ptp->tsevqs); @@ -139,9 +140,11 @@ int ptp_release(struct posix_clock *pc) long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg) { struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock); + struct timestamp_event_queue *tsevq, *tsevq_alt; struct ptp_sys_offset_extended *extoff = NULL; struct ptp_sys_offset_precise precise_offset; struct system_device_crosststamp xtstamp; + struct ptp_tsfilter_request tsfilter_req; struct ptp_clock_info *ops = ptp->info; struct ptp_sys_offset *sysoff = NULL; struct ptp_system_timestamp sts; @@ -451,6 +454,20 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg) mutex_unlock(&ptp->pincfg_mux); break; + case PTP_FILTERTS_REQUEST: + if (copy_from_user(&tsfilter_req, (void __user *)arg, + sizeof(tsfilter_req))) { + err = -EFAULT; + break; + } + list_for_each_entry_safe(tsevq, tsevq_alt, &ptp->tsevqs, qlist) { + if (tsevq->reader_pid == (pid_t)tsfilter_req.reader_pid) { + tsevq->tsevqmask = tsfilter_req.tsevqmask; + break; + } + } + break; + default: err = -ENOTTY; break; diff --git a/drivers/ptp/ptp_clock.c b/drivers/ptp/ptp_clock.c index d52fc23e20a8..9ebb78eb333f 100644 --- a/drivers/ptp/ptp_clock.c +++ b/drivers/ptp/ptp_clock.c @@ -247,6 +247,7 @@ struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info, if (!queue) goto no_memory_queue; queue->reader_pid = 0; + queue->tsevqmask = 0xFFFFFFFF; spin_lock_init(&queue->lock); list_add_tail(&queue->qlist, &ptp->tsevqs); mutex_init(&ptp->pincfg_mux); @@ -406,7 +407,8 @@ void ptp_clock_event(struct ptp_clock *ptp, struct ptp_clock_event *event) case PTP_CLOCK_EXTTS: /* Enqueue timestamp on all other queues */ list_for_each_entry_safe(tsevq, tsevq_alt, &ptp->tsevqs, qlist) { - enqueue_external_timestamp(tsevq, event); + if (tsevq->tsevqmask & (0x1 << event->index)) + enqueue_external_timestamp(tsevq, event); } wake_up_interruptible(&ptp->tsev_wq); break; diff --git a/drivers/ptp/ptp_private.h b/drivers/ptp/ptp_private.h index 046d1482bcee..6888ecb26e82 100644 --- a/drivers/ptp/ptp_private.h +++ b/drivers/ptp/ptp_private.h @@ -28,6 +28,7 @@ struct timestamp_event_queue { spinlock_t lock; struct list_head qlist; pid_t reader_pid; + int tsevqmask; }; struct ptp_clock { diff --git a/include/uapi/linux/ptp_clock.h b/include/uapi/linux/ptp_clock.h index 05cc35fc94ac..a13ab8e27703 100644 --- a/include/uapi/linux/ptp_clock.h +++ b/include/uapi/linux/ptp_clock.h @@ -105,6 +105,11 @@ struct ptp_extts_request { unsigned int rsv[2]; /* Reserved for future use. */ }; +struct ptp_tsfilter_request { + unsigned int reader_pid; /* PID of process reading the timestamp event queue */ + unsigned int tsevqmask; /* Channel mask. LSB = channel 0 */ +}; + struct ptp_perout_request { union { /* @@ -224,6 +229,8 @@ struct ptp_pin_desc { _IOWR(PTP_CLK_MAGIC, 17, struct ptp_sys_offset_precise) #define PTP_SYS_OFFSET_EXTENDED2 \ _IOWR(PTP_CLK_MAGIC, 18, struct ptp_sys_offset_extended) +#define PTP_FILTERTS_REQUEST \ + _IOW(PTP_CLK_MAGIC, 19, struct ptp_tsfilter_request) struct ptp_extts_event { struct ptp_clock_time t; /* Time event occured. */ diff --git a/tools/testing/selftests/ptp/testptp.c b/tools/testing/selftests/ptp/testptp.c index c9f6cca4feb4..e84ff689c6be 100644 --- a/tools/testing/selftests/ptp/testptp.c +++ b/tools/testing/selftests/ptp/testptp.c @@ -121,6 +121,7 @@ static void usage(char *progname) " -d name device to open\n" " -e val read 'val' external time stamp events\n" " -f val adjust the ptp clock frequency by 'val' ppb\n" + " -F pid,msk apply ts channel mask to queue open by pid\n" " -g get the ptp clock time\n" " -h prints this message\n" " -i val index for event/trigger\n" @@ -162,6 +163,7 @@ int main(int argc, char *argv[]) struct ptp_sys_offset *sysoff; struct ptp_sys_offset_extended *soe; struct ptp_sys_offset_precise *xts; + struct ptp_tsfilter_request tsfilter_req; char *progname; unsigned int i; @@ -194,9 +196,14 @@ int main(int argc, char *argv[]) int64_t pulsewidth = -1; int64_t perout = -1; + tsfilter_req.reader_pid = 0; + tsfilter_req.tsevqmask = 0xFFFFFFFF; + progname = strrchr(argv[0], '/'); progname = progname ? 1+progname : argv[0]; - while (EOF != (c = getopt(argc, argv, "cd:e:f:ghH:i:k:lL:n:o:p:P:sSt:T:w:x:Xz"))) { + while (EOF != + (c = getopt(argc, argv, + "cd:e:f:F:ghH:i:k:lL:n:o:p:P:sSt:T:w:x:Xz"))) { switch (c) { case 'c': capabilities = 1; @@ -210,6 +217,14 @@ int main(int argc, char *argv[]) case 'f': adjfreq = atoi(optarg); break; + case 'F': + cnt = sscanf(optarg, "%d,%X", &tsfilter_req.reader_pid, + &tsfilter_req.tsevqmask); + if (cnt != 2) { + usage(progname); + return -1; + } + break; case 'g': gettime = 1; break; @@ -604,6 +619,15 @@ int main(int argc, char *argv[]) free(xts); } + if (tsfilter_req.reader_pid != 0) { + if (ioctl(fd, PTP_FILTERTS_REQUEST, &tsfilter_req)) { + perror("PTP_FILTERTS_REQUEST"); + } else { + printf("Timestamp event queue mask 0x%X applied to reader with PID: %d\n", + (int)tsfilter_req.tsevqmask, tsfilter_req.reader_pid); + } + } + close(fd); return 0; }