diff options
author | Laurence Evans <levans@solarflare.com> | 2013-01-28 09:51:17 -0500 |
---|---|---|
committer | Ben Hutchings <bhutchings@solarflare.com> | 2013-12-06 17:15:55 -0500 |
commit | f32116003c39f3a6815215a7512e1ea8d1e4bbc7 (patch) | |
tree | e22346e109eb6108c9fe5fb805aa9a75311f6e7b | |
parent | e5a498e943fbc497f236ab8cf31366c75f337ce6 (diff) |
sfc: PTP: Moderate log message on event queue overflow
Limit syslog flood if a PTP packet storm occurs.
Fixes: 7c236c43b838 ('sfc: Add support for IEEE-1588 PTP')
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
-rw-r--r-- | drivers/net/ethernet/sfc/ptp.c | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/drivers/net/ethernet/sfc/ptp.c b/drivers/net/ethernet/sfc/ptp.c index 93a61a157d10..8b2cf783217c 100644 --- a/drivers/net/ethernet/sfc/ptp.c +++ b/drivers/net/ethernet/sfc/ptp.c | |||
@@ -220,6 +220,7 @@ struct efx_ptp_timeset { | |||
220 | * @evt_list: List of MC receive events awaiting packets | 220 | * @evt_list: List of MC receive events awaiting packets |
221 | * @evt_free_list: List of free events | 221 | * @evt_free_list: List of free events |
222 | * @evt_lock: Lock for manipulating evt_list and evt_free_list | 222 | * @evt_lock: Lock for manipulating evt_list and evt_free_list |
223 | * @evt_overflow: Boolean indicating that event list has overflowed | ||
223 | * @rx_evts: Instantiated events (on evt_list and evt_free_list) | 224 | * @rx_evts: Instantiated events (on evt_list and evt_free_list) |
224 | * @workwq: Work queue for processing pending PTP operations | 225 | * @workwq: Work queue for processing pending PTP operations |
225 | * @work: Work task | 226 | * @work: Work task |
@@ -270,6 +271,7 @@ struct efx_ptp_data { | |||
270 | struct list_head evt_list; | 271 | struct list_head evt_list; |
271 | struct list_head evt_free_list; | 272 | struct list_head evt_free_list; |
272 | spinlock_t evt_lock; | 273 | spinlock_t evt_lock; |
274 | bool evt_overflow; | ||
273 | struct efx_ptp_event_rx rx_evts[MAX_RECEIVE_EVENTS]; | 275 | struct efx_ptp_event_rx rx_evts[MAX_RECEIVE_EVENTS]; |
274 | struct workqueue_struct *workwq; | 276 | struct workqueue_struct *workwq; |
275 | struct work_struct work; | 277 | struct work_struct work; |
@@ -635,6 +637,11 @@ static void efx_ptp_drop_time_expired_events(struct efx_nic *efx) | |||
635 | } | 637 | } |
636 | } | 638 | } |
637 | } | 639 | } |
640 | /* If the event overflow flag is set and the event list is now empty | ||
641 | * clear the flag to re-enable the overflow warning message. | ||
642 | */ | ||
643 | if (ptp->evt_overflow && list_empty(&ptp->evt_list)) | ||
644 | ptp->evt_overflow = false; | ||
638 | spin_unlock_bh(&ptp->evt_lock); | 645 | spin_unlock_bh(&ptp->evt_lock); |
639 | } | 646 | } |
640 | 647 | ||
@@ -676,6 +683,11 @@ static enum ptp_packet_state efx_ptp_match_rx(struct efx_nic *efx, | |||
676 | break; | 683 | break; |
677 | } | 684 | } |
678 | } | 685 | } |
686 | /* If the event overflow flag is set and the event list is now empty | ||
687 | * clear the flag to re-enable the overflow warning message. | ||
688 | */ | ||
689 | if (ptp->evt_overflow && list_empty(&ptp->evt_list)) | ||
690 | ptp->evt_overflow = false; | ||
679 | spin_unlock_bh(&ptp->evt_lock); | 691 | spin_unlock_bh(&ptp->evt_lock); |
680 | 692 | ||
681 | return rc; | 693 | return rc; |
@@ -809,6 +821,7 @@ static int efx_ptp_stop(struct efx_nic *efx) | |||
809 | list_for_each_safe(cursor, next, &efx->ptp_data->evt_list) { | 821 | list_for_each_safe(cursor, next, &efx->ptp_data->evt_list) { |
810 | list_move(cursor, &efx->ptp_data->evt_free_list); | 822 | list_move(cursor, &efx->ptp_data->evt_free_list); |
811 | } | 823 | } |
824 | ptp->evt_overflow = false; | ||
812 | spin_unlock_bh(&efx->ptp_data->evt_lock); | 825 | spin_unlock_bh(&efx->ptp_data->evt_lock); |
813 | 826 | ||
814 | return rc; | 827 | return rc; |
@@ -901,6 +914,7 @@ static int efx_ptp_probe_channel(struct efx_channel *channel) | |||
901 | spin_lock_init(&ptp->evt_lock); | 914 | spin_lock_init(&ptp->evt_lock); |
902 | for (pos = 0; pos < MAX_RECEIVE_EVENTS; pos++) | 915 | for (pos = 0; pos < MAX_RECEIVE_EVENTS; pos++) |
903 | list_add(&ptp->rx_evts[pos].link, &ptp->evt_free_list); | 916 | list_add(&ptp->rx_evts[pos].link, &ptp->evt_free_list); |
917 | ptp->evt_overflow = false; | ||
904 | 918 | ||
905 | ptp->phc_clock_info.owner = THIS_MODULE; | 919 | ptp->phc_clock_info.owner = THIS_MODULE; |
906 | snprintf(ptp->phc_clock_info.name, | 920 | snprintf(ptp->phc_clock_info.name, |
@@ -1299,8 +1313,13 @@ static void ptp_event_rx(struct efx_nic *efx, struct efx_ptp_data *ptp) | |||
1299 | list_add_tail(&evt->link, &ptp->evt_list); | 1313 | list_add_tail(&evt->link, &ptp->evt_list); |
1300 | 1314 | ||
1301 | queue_work(ptp->workwq, &ptp->work); | 1315 | queue_work(ptp->workwq, &ptp->work); |
1302 | } else { | 1316 | } else if (!ptp->evt_overflow) { |
1303 | netif_err(efx, rx_err, efx->net_dev, "No free PTP event"); | 1317 | /* Log a warning message and set the event overflow flag. |
1318 | * The message won't be logged again until the event queue | ||
1319 | * becomes empty. | ||
1320 | */ | ||
1321 | netif_err(efx, rx_err, efx->net_dev, "PTP event queue overflow\n"); | ||
1322 | ptp->evt_overflow = true; | ||
1304 | } | 1323 | } |
1305 | spin_unlock_bh(&ptp->evt_lock); | 1324 | spin_unlock_bh(&ptp->evt_lock); |
1306 | } | 1325 | } |