From patchwork Wed Sep 6 10:47:52 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xabier Marquiegui X-Patchwork-Id: 13375518 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 BAE487E for ; Wed, 6 Sep 2023 10:48:14 +0000 (UTC) Received: from mail-wm1-x330.google.com (mail-wm1-x330.google.com [IPv6:2a00:1450:4864:20::330]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C426910F9 for ; Wed, 6 Sep 2023 03:48:01 -0700 (PDT) Received: by mail-wm1-x330.google.com with SMTP id 5b1f17b1804b1-401b5516104so34424025e9.2 for ; Wed, 06 Sep 2023 03:48:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1693997280; x=1694602080; 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=TJUmuSIwPiuMBs8OmdGVOt9Y6L2l5R1BUyhmQJoQeNU=; b=K0XWrDmbqQ3JQMPrgIfkOOHYP8EkL7at6gnJaamrhPt+Akl2lxmznm/mfwYv4XFfWj Nf7Mt3DczZczE+fIOmZ2eH6RF+IZUGOm7QJKa2UxCgk0mX0tSqGiuY/NwJRP2+MxUjl2 B780Rxs0zIWyiPIRAtpBKgI6owangkkxdzv8AcAnsdGZwgw3IhRTlV2oSSstSMMGxzF5 eDFQlU/ryH+PUM9rl7FJsPGRY5BJdqhNvB5M6CXFIk89LyJp3TAjHWn8NXqd8jQJYmNz WUmbIRRNP/lujoGCaJHyySrivOGb540JURFQnYGWVu/CYvON714cKmTaCzrhNZ99gZRF 0NnA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1693997280; x=1694602080; 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=TJUmuSIwPiuMBs8OmdGVOt9Y6L2l5R1BUyhmQJoQeNU=; b=C3zSb79MJsV08/SZtpWA3rFznZnA/0v+qTgeZoNWwOlMMIvmT32BwtemrqTkfYB00/ K3aL5N+kXtFA2moGi/yEDFACBdYWU+/q/4abuJM+IYSjlwULw46/1CI1JrshACpqfion J9F9Kci2FVKm3VszpbVlzHszoRZPUbgbsU2yOxfmlPOcZZWD7+5RFz4Yev9Eix3jWtsk a5F8cpPui0JiYc2IVFu2cwXPYoyqXnRa5zI5InHw7WOy8c9QPRdwkviEEiiu+jCP765S px6eFfpCjawvYrfquNPWfGY36Oka5eUHW6yQpl7JhEanz3Gu0opih1sPDoO0lF0QiteD Nh8Q== X-Gm-Message-State: AOJu0Yx1XXEVp0jb6DffKPDulh7Kav3xyj24hDGQphjyz8NFtk8i7Tc0 fixB2qQGj34nxnpG80HbeKs= X-Google-Smtp-Source: AGHT+IEzI+0C1LWBQvmFf0PkNmMwx7koI3/2ibrOfqmURV502fawq1KVv2dtJYhi3ynJn6vq2yAOIg== X-Received: by 2002:a7b:cb96:0:b0:3fe:d6bf:f314 with SMTP id m22-20020a7bcb96000000b003fed6bff314mr1879161wmi.39.1693997280048; Wed, 06 Sep 2023 03:48:00 -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 l7-20020a7bc447000000b003fe1fe56202sm19508728wmi.33.2023.09.06.03.47.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 06 Sep 2023 03:47:59 -0700 (PDT) From: Xabier Marquiegui To: richardcochran@gmail.com Cc: chrony-dev@chrony.tuxfamily.org, mlichvar@redhat.com, netdev@vger.kernel.org, ntp-lists@mattcorallo.com, reibax@gmail.com Subject: [PATCH 1/3] ptp: Replace timestamp event queue with linked list Date: Wed, 6 Sep 2023 12:47:52 +0200 Message-Id: <20230906104754.1324412-2-reibax@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230906104754.1324412-1-reibax@gmail.com> References: <20230906104754.1324412-1-reibax@gmail.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_BLOCKED,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net 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 --- drivers/ptp/ptp_chardev.c | 18 ++++++++++++++++-- drivers/ptp/ptp_clock.c | 30 ++++++++++++++++++++++++++++-- drivers/ptp/ptp_private.h | 4 +++- drivers/ptp/ptp_sysfs.c | 6 +++++- 4 files changed, 52 insertions(+), 6 deletions(-) diff --git a/drivers/ptp/ptp_chardev.c b/drivers/ptp/ptp_chardev.c index 362bf756e6b7..1ea11f864abb 100644 --- a/drivers/ptp/ptp_chardev.c +++ b/drivers/ptp/ptp_chardev.c @@ -435,10 +435,17 @@ 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 +454,19 @@ 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..dd48b9f41535 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 list_head *pos; + struct timestamp_event_queue *element; + + 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(struct timestamp_event_queue), GFP_KERNEL); + if (queue == NULL) + 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); @@ -376,6 +398,7 @@ EXPORT_SYMBOL(ptp_clock_unregister); void ptp_clock_event(struct ptp_clock *ptp, struct ptp_clock_event *event) { struct pps_event_time evt; + struct timestamp_event_queue *tsevq, *tsevq_alt; 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..014293255677 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; /* Link to other queues */ }; 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 Wed Sep 6 10:47:53 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xabier Marquiegui X-Patchwork-Id: 13375519 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 470B17E for ; Wed, 6 Sep 2023 10:48:19 +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 D8C80199F for ; Wed, 6 Sep 2023 03:48:03 -0700 (PDT) Received: by mail-wm1-x335.google.com with SMTP id 5b1f17b1804b1-40078c4855fso34392645e9.3 for ; Wed, 06 Sep 2023 03:48:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1693997282; x=1694602082; 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=65gwA4q5n+YpII0wBkIL+YWS0or2Y/v+uHr6EorpFpE=; b=pLRFTfCAxACbJQ2A4xjLjA2aLIn+tck+Auti70cGQzoo0SFD1e2OmHPULGOPxsmyL4 FImBYWzKMogeVkvNsqyjSdV1OMyulR4rPhfynBgMvtY/kn6/azvbYKgH4qR/C/AVpxgx ixIbze9nnBGod1kkFbicbwkDb8i844kt7c68BZPyEAPMd/bMq+rTGSj/2b1yYe84wW8q wMwb1aJ7zdKLIjTKk+ppPMIDxx55+Iv7Za44bL8bRv9ewj/ZxSGuNRkSljm3eEctOWXa 0g4igekdjHTPkjjAioC+G2t82YqjWPy/N5CkXj7nh3P4N48e9MuPaoh2u8iY3tURs/7v +gcw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1693997282; x=1694602082; 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=65gwA4q5n+YpII0wBkIL+YWS0or2Y/v+uHr6EorpFpE=; b=KbcsHmpIao2+/nHfjCtA9QEOLwavP1MMWF/CpWN66FAC8ANB6u8Sl10b90FMNHcx87 ycrn8MutyVj87EJVEYg7uf9dtYoqquj9/VBtawH0NY7ytMUlsBmH2dihMMgCaPPw0rlY vq5Wj/0bEy9sn/0Dg1U9OCFMXV6J7W5Gr1di/aG3NV/aPmlm4H3PhG0tAFKBO398ZKXa gLVkUKxzdsz1WuA4DcZk37N/SlZMLqHQK+GbuJ3yzj3L/SaIouZfdL/kGmbFZxqZ71MY uynYWOJuJmCgGcC2cb28YgIB2/VDUd7ftNoGiO5Ah1YnJqJDPQlUCm+fb4ItYY7gFK/H dykg== X-Gm-Message-State: AOJu0YwWUJMejmHFn40LezzCjvR5ptX1YPvWnLwXrUEnNod2ejN8JQY3 VO99yucON+RzeoUJ0+1nt40= X-Google-Smtp-Source: AGHT+IGMhbEVU+oaksMiBWnBkokfA4jafJIjVvSpdlpBOuhYaujIBO+IRyqMnl3GVdY/AL7AwFS2hg== X-Received: by 2002:a05:600c:b88:b0:402:e68f:888a with SMTP id fl8-20020a05600c0b8800b00402e68f888amr619304wmb.3.1693997282238; Wed, 06 Sep 2023 03:48:02 -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 l7-20020a7bc447000000b003fe1fe56202sm19508728wmi.33.2023.09.06.03.48.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 06 Sep 2023 03:48:02 -0700 (PDT) From: Xabier Marquiegui To: richardcochran@gmail.com Cc: chrony-dev@chrony.tuxfamily.org, mlichvar@redhat.com, netdev@vger.kernel.org, ntp-lists@mattcorallo.com, reibax@gmail.com Subject: [PATCH 2/3] ptp: support multiple timestamp event readers Date: Wed, 6 Sep 2023 12:47:53 +0200 Message-Id: <20230906104754.1324412-3-reibax@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230906104754.1324412-1-reibax@gmail.com> References: <20230906104754.1324412-1-reibax@gmail.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_BLOCKED,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net 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 --- drivers/ptp/ptp_chardev.c | 95 ++++++++++++++++++++++++++++++--------- drivers/ptp/ptp_clock.c | 6 +-- drivers/ptp/ptp_private.h | 4 +- drivers/ptp/ptp_sysfs.c | 4 -- 4 files changed, 80 insertions(+), 29 deletions(-) diff --git a/drivers/ptp/ptp_chardev.c b/drivers/ptp/ptp_chardev.c index 1ea11f864abb..c65dc6fefaa6 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(struct timestamp_event_queue), GFP_KERNEL); + if (queue == NULL) + 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); @@ -436,14 +466,25 @@ __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; + struct list_head *pos, *n; + bool found = false; + pid_t reader_pid = task_pid_nr(current); poll_wait(fp, &ptp->tsev_wq, wait); /* - * Extract only the first element in the queue list - * TODO: Identify the relevant queue + * Extract only the desired element in the queue list */ - queue = list_entry(&ptp->tsevqs, struct timestamp_event_queue, qlist); + 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 -EINVAL; return queue_cnt(queue) ? EPOLLIN : 0; } @@ -459,40 +500,50 @@ ssize_t ptp_read(struct posix_clock *pc, unsigned long flags; size_t qcnt, i; int result; + struct list_head *pos, *n; + bool found = false; + pid_t reader_pid = task_pid_nr(current); /* - * Extract only the first element in the queue list - * TODO: Identify the relevant queue + * Extract only the desired element in the queue list */ - queue = list_first_entry(&ptp->tsevqs, struct timestamp_event_queue, - qlist); + 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; } 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); @@ -511,12 +562,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 dd48b9f41535..dc2f045cacbd 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(struct timestamp_event_queue), GFP_KERNEL); if (queue == NULL) 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 014293255677..56b0c9df188d 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; /* Link to other queues */ + 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 Wed Sep 6 10:47:54 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xabier Marquiegui X-Patchwork-Id: 13375520 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 A5CC97E for ; Wed, 6 Sep 2023 10:48:22 +0000 (UTC) Received: from mail-wr1-x42a.google.com (mail-wr1-x42a.google.com [IPv6:2a00:1450:4864:20::42a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D166119AE for ; Wed, 6 Sep 2023 03:48:05 -0700 (PDT) Received: by mail-wr1-x42a.google.com with SMTP id ffacd0b85a97d-31ad779e6b3so2945566f8f.2 for ; Wed, 06 Sep 2023 03:48:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1693997284; x=1694602084; 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=h1x2ARNgqgBpb5WeTLouss9577WddXe/XTJzMBKADGg=; b=IQN3YAzRTjlL/DOPLtqXVqJfNmV75xKOu1sxNa2S7bbyoVpA28UwlRHcyQFSP50iM6 myyM63moSDz0EtBCbaFUyny466xsbNytn2FGIbZsSVefRHItn1Kkt0r2m815a57CuZuy IU71ZOcyHOkzfPCx6XWKhzvwpoIGUPCxYzgB4aJTPEaaQwqQJ7setXgbyzSCXXVyyUi0 qGuW+Au0tHNcKq0ef9h+HW9hxHo7GN6aYpQyuDzg2h4MexTUDOgh2QXWvbprAZ2IwhC9 K/3+YOIZdP8NYqBlNxbBF42zVeMfNklTr1u0McmwpG+HLZzrxhsEQu7fHdKA34m/wOAw up1A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1693997284; x=1694602084; 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=h1x2ARNgqgBpb5WeTLouss9577WddXe/XTJzMBKADGg=; b=mAEqZEwtXf2rY+xNrL2GK7MqW7QaUZ7+Nel67cHav60hTU44OWFCHakWYw6dizaZgx LROOZZUfps49iDSnOx1y+8Fxp7XEn4/NQIVG/tknlRE6B9oH4GNUzh9qhJqLImTCbPh8 fQoP8XSan8A6JALQWIikG8Jr8pJFgxAUhraFk/V1Mafy3hvyR60DNhdrnCszOieSB4Gu WvXQ2JQ9+1ph5rSi75o6C0On2M4glMZ+a3B0qoInm1tbTuZplAbl/YMKeJw5k4kyBGLj 1uATSwu7sfqUwqHXpVC+T4QVslynZhXn8KWtmaxtAIre57JkxjoGxALxwnOuVKKtmixk HEqA== X-Gm-Message-State: AOJu0Yxm34JRWrRgaiYYfNOkLg33Zu0i1fnMlNmFqO53EjTCB7RaTEFr CSHeOBgAfMIMMKP02X620xk= X-Google-Smtp-Source: AGHT+IH/ZX/O1bflMQW1o0cz02tFkVkvyj+Uw7NqBvWz0cC587h92qO9BZcWtr1MZ8/IJiPomRFvlw== X-Received: by 2002:adf:f6cc:0:b0:317:5c36:913b with SMTP id y12-20020adff6cc000000b003175c36913bmr2016067wrp.48.1693997284082; Wed, 06 Sep 2023 03:48:04 -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 l7-20020a7bc447000000b003fe1fe56202sm19508728wmi.33.2023.09.06.03.48.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 06 Sep 2023 03:48:03 -0700 (PDT) From: Xabier Marquiegui To: richardcochran@gmail.com Cc: chrony-dev@chrony.tuxfamily.org, mlichvar@redhat.com, netdev@vger.kernel.org, ntp-lists@mattcorallo.com, reibax@gmail.com Subject: [PATCH 3/3] ptp: support event queue reader channel masks Date: Wed, 6 Sep 2023 12:47:54 +0200 Message-Id: <20230906104754.1324412-4-reibax@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230906104754.1324412-1-reibax@gmail.com> References: <20230906104754.1324412-1-reibax@gmail.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_BLOCKED,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net 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. Signed-off-by: Xabier Marquiegui --- 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 c65dc6fefaa6..72697189ac59 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(struct timestamp_event_queue), GFP_KERNEL); if (queue == NULL) return -EINVAL; + queue->mask = 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 == tsfilter_req.reader_pid) { + tsevq->mask = tsfilter_req.mask; + break; + } + } + break; + default: err = -ENOTTY; break; diff --git a/drivers/ptp/ptp_clock.c b/drivers/ptp/ptp_clock.c index dc2f045cacbd..360bd5f9d759 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 == NULL) goto no_memory_queue; queue->reader_pid = 0; + queue->mask = 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->mask & (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 56b0c9df188d..07f9e6b64e99 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; /* Link to other queues */ pid_t reader_pid; + int mask; }; struct ptp_clock { diff --git a/include/uapi/linux/ptp_clock.h b/include/uapi/linux/ptp_clock.h index 05cc35fc94ac..372d0a1dc6f7 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 { + pid_t reader_pid; /* PID of process reading the timestamp event queue */ + unsigned int mask; /* 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..8c4d40c16cdf 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.mask = 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.mask); + 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.mask, tsfilter_req.reader_pid); + } + } + close(fd); return 0; }