--- x/drivers/ptp/ptp_chardev.c 2023-10-28 09:05:49.716916500 +0800 +++ y/drivers/ptp/ptp_chardev.c 2023-10-28 19:23:39.463658000 +0800 @@ -108,6 +108,7 @@ int ptp_open(struct posix_clock_context container_of(pccontext->clk, struct ptp_clock, clock); struct timestamp_event_queue *queue; char debugfsname[32]; + unsigned long flags; queue = kzalloc(sizeof(*queue), GFP_KERNEL); if (!queue) @@ -119,7 +120,9 @@ int ptp_open(struct posix_clock_context } bitmap_set(queue->mask, 0, PTP_MAX_CHANNELS); spin_lock_init(&queue->lock); + spin_lock_irqsave(&ptp->qlock, flags); list_add_tail(&queue->qlist, &ptp->tsevqs); + spin_unlock_irqrestore(&ptp->qlock, flags); pccontext->private_clkdata = queue; /* Debugfs contents */ @@ -139,13 +142,14 @@ int ptp_release(struct posix_clock_conte { struct timestamp_event_queue *queue = pccontext->private_clkdata; unsigned long flags; + struct ptp_clock *ptp = container_of(pccontext->clk, struct ptp_clock, clock); if (queue) { debugfs_remove(queue->debugfs_instance); pccontext->private_clkdata = NULL; - spin_lock_irqsave(&queue->lock, flags); + spin_lock_irqsave(&ptp->qlock, flags); list_del(&queue->qlist); - spin_unlock_irqrestore(&queue->lock, flags); + spin_unlock_irqrestore(&ptp->qlock, flags); bitmap_free(queue->mask); kfree(queue); } --- x/drivers/ptp/ptp_clock.c 2023-10-28 19:07:40.161237900 +0800 +++ y/drivers/ptp/ptp_clock.c 2023-10-28 19:18:55.005187700 +0800 @@ -179,11 +179,10 @@ static void ptp_clock_release(struct dev mutex_destroy(&ptp->pincfg_mux); mutex_destroy(&ptp->n_vclocks_mux); /* Delete first entry */ - tsevq = list_first_entry(&ptp->tsevqs, struct timestamp_event_queue, - qlist); - spin_lock_irqsave(&tsevq->lock, flags); + spin_lock_irqsave(&ptp->qlock, flags); + tsevq = list_first_entry(&ptp->tsevqs, struct timestamp_event_queue, qlist); list_del(&tsevq->qlist); - spin_unlock_irqrestore(&tsevq->lock, flags); + spin_unlock_irqrestore(&ptp->qlock, flags); bitmap_free(tsevq->mask); kfree(tsevq); debugfs_remove(ptp->debugfs_root); @@ -243,6 +242,7 @@ struct ptp_clock *ptp_clock_register(str ptp->devid = MKDEV(major, index); ptp->index = index; INIT_LIST_HEAD(&ptp->tsevqs); + spin_lock_init(&ptp->qlock); queue = kzalloc(sizeof(*queue), GFP_KERNEL); if (!queue) goto no_memory_queue; @@ -407,6 +407,7 @@ void ptp_clock_event(struct ptp_clock *p { struct timestamp_event_queue *tsevq; struct pps_event_time evt; + unsigned long flags; switch (event->type) { @@ -415,10 +416,12 @@ void ptp_clock_event(struct ptp_clock *p case PTP_CLOCK_EXTTS: /* Enqueue timestamp on selected queues */ + spin_lock_irqsave(&ptp->qlock, flags); list_for_each_entry(tsevq, &ptp->tsevqs, qlist) { if (test_bit((unsigned int)event->index, tsevq->mask)) enqueue_external_timestamp(tsevq, event); } + spin_unlock_irqrestore(&ptp->qlock, flags); wake_up_interruptible(&ptp->tsev_wq); break; --- x/drivers/ptp/ptp_private.h 2023-10-28 19:07:40.172063600 +0800 +++ y/drivers/ptp/ptp_private.h 2023-10-28 19:09:49.337895700 +0800 @@ -41,6 +41,7 @@ struct ptp_clock { struct ptp_clock_info *info; dev_t devid; int index; /* index into clocks.map */ + spinlock_t qlock; struct pps_device *pps_source; long dialed_frequency; /* remembers the frequency adjustment */ struct list_head tsevqs; /* timestamp fifo list */