Skip to content

Commit d26ab5a

Browse files
reibax-marcusdavem330
authored andcommitted
ptp: Replace timestamp event queue with linked list
Introduce linked lists to access the timestamp event queue. Signed-off-by: Xabier Marquiegui <[email protected]> Suggested-by: Richard Cochran <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 60c6946 commit d26ab5a

File tree

4 files changed

+42
-6
lines changed

4 files changed

+42
-6
lines changed

drivers/ptp/ptp_chardev.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -439,10 +439,14 @@ __poll_t ptp_poll(struct posix_clock_context *pccontext, struct file *fp,
439439
{
440440
struct ptp_clock *ptp =
441441
container_of(pccontext->clk, struct ptp_clock, clock);
442+
struct timestamp_event_queue *queue;
442443

443444
poll_wait(fp, &ptp->tsev_wq, wait);
444445

445-
return queue_cnt(&ptp->tsevq) ? EPOLLIN : 0;
446+
/* Extract only the first element in the queue list */
447+
queue = list_first_entry(&ptp->tsevqs, struct timestamp_event_queue, qlist);
448+
449+
return queue_cnt(queue) ? EPOLLIN : 0;
446450
}
447451

448452
#define EXTTS_BUFSIZE (PTP_BUF_TIMESTAMPS * sizeof(struct ptp_extts_event))
@@ -452,12 +456,16 @@ ssize_t ptp_read(struct posix_clock_context *pccontext, uint rdflags,
452456
{
453457
struct ptp_clock *ptp =
454458
container_of(pccontext->clk, struct ptp_clock, clock);
455-
struct timestamp_event_queue *queue = &ptp->tsevq;
459+
struct timestamp_event_queue *queue;
456460
struct ptp_extts_event *event;
457461
unsigned long flags;
458462
size_t qcnt, i;
459463
int result;
460464

465+
/* Extract only the first element in the queue list */
466+
queue = list_first_entry(&ptp->tsevqs, struct timestamp_event_queue,
467+
qlist);
468+
461469
if (cnt % sizeof(struct ptp_extts_event) != 0)
462470
return -EINVAL;
463471

drivers/ptp/ptp_clock.c

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -169,12 +169,21 @@ static struct posix_clock_operations ptp_clock_ops = {
169169
static void ptp_clock_release(struct device *dev)
170170
{
171171
struct ptp_clock *ptp = container_of(dev, struct ptp_clock, dev);
172+
struct timestamp_event_queue *tsevq;
173+
unsigned long flags;
172174

173175
ptp_cleanup_pin_groups(ptp);
174176
kfree(ptp->vclock_index);
175177
mutex_destroy(&ptp->tsevq_mux);
176178
mutex_destroy(&ptp->pincfg_mux);
177179
mutex_destroy(&ptp->n_vclocks_mux);
180+
/* Delete first entry */
181+
tsevq = list_first_entry(&ptp->tsevqs, struct timestamp_event_queue,
182+
qlist);
183+
spin_lock_irqsave(&tsevq->lock, flags);
184+
list_del(&tsevq->qlist);
185+
spin_unlock_irqrestore(&tsevq->lock, flags);
186+
kfree(tsevq);
178187
ida_free(&ptp_clocks_map, ptp->index);
179188
kfree(ptp);
180189
}
@@ -206,6 +215,7 @@ struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info,
206215
struct device *parent)
207216
{
208217
struct ptp_clock *ptp;
218+
struct timestamp_event_queue *queue = NULL;
209219
int err = 0, index, major = MAJOR(ptp_devt);
210220
size_t size;
211221

@@ -228,7 +238,12 @@ struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info,
228238
ptp->info = info;
229239
ptp->devid = MKDEV(major, index);
230240
ptp->index = index;
231-
spin_lock_init(&ptp->tsevq.lock);
241+
INIT_LIST_HEAD(&ptp->tsevqs);
242+
queue = kzalloc(sizeof(*queue), GFP_KERNEL);
243+
if (!queue)
244+
goto no_memory_queue;
245+
spin_lock_init(&queue->lock);
246+
list_add_tail(&queue->qlist, &ptp->tsevqs);
232247
mutex_init(&ptp->tsevq_mux);
233248
mutex_init(&ptp->pincfg_mux);
234249
mutex_init(&ptp->n_vclocks_mux);
@@ -333,6 +348,9 @@ struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info,
333348
mutex_destroy(&ptp->tsevq_mux);
334349
mutex_destroy(&ptp->pincfg_mux);
335350
mutex_destroy(&ptp->n_vclocks_mux);
351+
list_del(&queue->qlist);
352+
kfree(queue);
353+
no_memory_queue:
336354
ida_free(&ptp_clocks_map, index);
337355
no_slot:
338356
kfree(ptp);
@@ -375,6 +393,7 @@ EXPORT_SYMBOL(ptp_clock_unregister);
375393

376394
void ptp_clock_event(struct ptp_clock *ptp, struct ptp_clock_event *event)
377395
{
396+
struct timestamp_event_queue *tsevq;
378397
struct pps_event_time evt;
379398

380399
switch (event->type) {
@@ -383,7 +402,10 @@ void ptp_clock_event(struct ptp_clock *ptp, struct ptp_clock_event *event)
383402
break;
384403

385404
case PTP_CLOCK_EXTTS:
386-
enqueue_external_timestamp(&ptp->tsevq, event);
405+
/* Enqueue timestamp on all queues */
406+
list_for_each_entry(tsevq, &ptp->tsevqs, qlist) {
407+
enqueue_external_timestamp(tsevq, event);
408+
}
387409
wake_up_interruptible(&ptp->tsev_wq);
388410
break;
389411

drivers/ptp/ptp_private.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <linux/ptp_clock.h>
1616
#include <linux/ptp_clock_kernel.h>
1717
#include <linux/time.h>
18+
#include <linux/list.h>
1819

1920
#define PTP_MAX_TIMESTAMPS 128
2021
#define PTP_BUF_TIMESTAMPS 30
@@ -25,6 +26,7 @@ struct timestamp_event_queue {
2526
int head;
2627
int tail;
2728
spinlock_t lock;
29+
struct list_head qlist;
2830
};
2931

3032
struct ptp_clock {
@@ -35,7 +37,7 @@ struct ptp_clock {
3537
int index; /* index into clocks.map */
3638
struct pps_device *pps_source;
3739
long dialed_frequency; /* remembers the frequency adjustment */
38-
struct timestamp_event_queue tsevq; /* simple fifo for time stamps */
40+
struct list_head tsevqs; /* timestamp fifo list */
3941
struct mutex tsevq_mux; /* one process at a time reading the fifo */
4042
struct mutex pincfg_mux; /* protect concurrent info->pin_config access */
4143
wait_queue_head_t tsev_wq;

drivers/ptp/ptp_sysfs.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,12 +75,16 @@ static ssize_t extts_fifo_show(struct device *dev,
7575
struct device_attribute *attr, char *page)
7676
{
7777
struct ptp_clock *ptp = dev_get_drvdata(dev);
78-
struct timestamp_event_queue *queue = &ptp->tsevq;
78+
struct timestamp_event_queue *queue;
7979
struct ptp_extts_event event;
8080
unsigned long flags;
8181
size_t qcnt;
8282
int cnt = 0;
8383

84+
/* The sysfs fifo will always draw from the fist queue */
85+
queue = list_first_entry(&ptp->tsevqs, struct timestamp_event_queue,
86+
qlist);
87+
8488
memset(&event, 0, sizeof(event));
8589

8690
if (mutex_lock_interruptible(&ptp->tsevq_mux))

0 commit comments

Comments
 (0)