ena.c (637ff00f2f9bd6c8509d0e2ac8959c7a23f09650) ena.c (a33ec635d1f6d574d54e6f6d74766d070183be4c)
1/*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (c) 2015-2024 Amazon.com, Inc. or its affiliates.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

--- 155 unchanged lines hidden (view full) ---

164 struct ena_com_dev_get_features_ctx *, int *);
165static int ena_enable_msix_and_set_admin_interrupts(struct ena_adapter *);
166static void ena_update_on_link_change(void *, struct ena_admin_aenq_entry *);
167static void unimplemented_aenq_handler(void *, struct ena_admin_aenq_entry *);
168static int ena_copy_eni_metrics(struct ena_adapter *);
169static int ena_copy_srd_metrics(struct ena_adapter *);
170static int ena_copy_customer_metrics(struct ena_adapter *);
171static void ena_timer_service(void *);
1/*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (c) 2015-2024 Amazon.com, Inc. or its affiliates.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

--- 155 unchanged lines hidden (view full) ---

164 struct ena_com_dev_get_features_ctx *, int *);
165static int ena_enable_msix_and_set_admin_interrupts(struct ena_adapter *);
166static void ena_update_on_link_change(void *, struct ena_admin_aenq_entry *);
167static void unimplemented_aenq_handler(void *, struct ena_admin_aenq_entry *);
168static int ena_copy_eni_metrics(struct ena_adapter *);
169static int ena_copy_srd_metrics(struct ena_adapter *);
170static int ena_copy_customer_metrics(struct ena_adapter *);
171static void ena_timer_service(void *);
172static enum ena_regs_reset_reason_types check_cdesc_in_tx_cq(struct ena_adapter *,
173 struct ena_ring *);
172
174
175
173static char ena_version[] = ENA_DEVICE_NAME ENA_DRV_MODULE_NAME
174 " v" ENA_DRV_MODULE_VERSION;
175
176static ena_vendor_info_t ena_vendor_info_array[] = {
177 { PCI_VENDOR_ID_AMAZON, PCI_DEV_ID_ENA_PF, 0 },
178 { PCI_VENDOR_ID_AMAZON, PCI_DEV_ID_ENA_PF_RSERV0, 0 },
179 { PCI_VENDOR_ID_AMAZON, PCI_DEV_ID_ENA_VF, 0 },
180 { PCI_VENDOR_ID_AMAZON, PCI_DEV_ID_ENA_VF_RSERV0, 0 },

--- 2902 unchanged lines hidden (view full) ---

3083 rx_ring->qid);
3084 ena_trigger_reset(adapter, ENA_REGS_RESET_MISS_INTERRUPT);
3085 return (EIO);
3086 }
3087
3088 return (0);
3089}
3090
176static char ena_version[] = ENA_DEVICE_NAME ENA_DRV_MODULE_NAME
177 " v" ENA_DRV_MODULE_VERSION;
178
179static ena_vendor_info_t ena_vendor_info_array[] = {
180 { PCI_VENDOR_ID_AMAZON, PCI_DEV_ID_ENA_PF, 0 },
181 { PCI_VENDOR_ID_AMAZON, PCI_DEV_ID_ENA_PF_RSERV0, 0 },
182 { PCI_VENDOR_ID_AMAZON, PCI_DEV_ID_ENA_VF, 0 },
183 { PCI_VENDOR_ID_AMAZON, PCI_DEV_ID_ENA_VF_RSERV0, 0 },

--- 2902 unchanged lines hidden (view full) ---

3086 rx_ring->qid);
3087 ena_trigger_reset(adapter, ENA_REGS_RESET_MISS_INTERRUPT);
3088 return (EIO);
3089 }
3090
3091 return (0);
3092}
3093
3094static enum ena_regs_reset_reason_types
3095check_cdesc_in_tx_cq(struct ena_adapter *adapter,
3096 struct ena_ring *tx_ring)
3097{
3098 device_t pdev = adapter->pdev;
3099 int rc;
3100 u16 req_id;
3101
3102 rc = ena_com_tx_comp_req_id_get(tx_ring->ena_com_io_cq, &req_id);
3103 /* TX CQ is empty */
3104 if (rc == ENA_COM_TRY_AGAIN) {
3105 ena_log(pdev, ERR,
3106 "No completion descriptors found in CQ %d\n",
3107 tx_ring->qid);
3108 return ENA_REGS_RESET_MISS_TX_CMPL;
3109 }
3110
3111 /* TX CQ has cdescs */
3112 ena_log(pdev, ERR,
3113 "Completion descriptors found in CQ %d",
3114 tx_ring->qid);
3115
3116 return ENA_REGS_RESET_MISS_INTERRUPT;
3117}
3118
3091static int
3092check_missing_comp_in_tx_queue(struct ena_adapter *adapter,
3093 struct ena_ring *tx_ring)
3094{
3095 uint32_t missed_tx = 0, new_missed_tx = 0;
3096 device_t pdev = adapter->pdev;
3097 struct bintime curtime, time;
3098 struct ena_tx_buffer *tx_buf;
3099 int time_since_last_cleanup;
3100 int missing_tx_comp_to;
3101 sbintime_t time_offset;
3102 int i, rc = 0;
3119static int
3120check_missing_comp_in_tx_queue(struct ena_adapter *adapter,
3121 struct ena_ring *tx_ring)
3122{
3123 uint32_t missed_tx = 0, new_missed_tx = 0;
3124 device_t pdev = adapter->pdev;
3125 struct bintime curtime, time;
3126 struct ena_tx_buffer *tx_buf;
3127 int time_since_last_cleanup;
3128 int missing_tx_comp_to;
3129 sbintime_t time_offset;
3130 int i, rc = 0;
3131 enum ena_regs_reset_reason_types reset_reason = ENA_REGS_RESET_MISS_TX_CMPL;
3132 bool cleanup_scheduled, cleanup_running;
3103
3104 getbinuptime(&curtime);
3105
3106 for (i = 0; i < tx_ring->ring_size; i++) {
3107 tx_buf = &tx_ring->tx_buffer_info[i];
3108
3109 if (bintime_isset(&tx_buf->timestamp) == 0)
3110 continue;

--- 39 unchanged lines hidden (view full) ---

3150 }
3151 }
3152 /* Checking if this TX ring missing TX completions have passed the threshold */
3153 if (unlikely(missed_tx > adapter->missing_tx_threshold)) {
3154 ena_log(pdev, ERR,
3155 "The number of lost tx completion is above the threshold "
3156 "(%d > %d). Reset the device\n",
3157 missed_tx, adapter->missing_tx_threshold);
3133
3134 getbinuptime(&curtime);
3135
3136 for (i = 0; i < tx_ring->ring_size; i++) {
3137 tx_buf = &tx_ring->tx_buffer_info[i];
3138
3139 if (bintime_isset(&tx_buf->timestamp) == 0)
3140 continue;

--- 39 unchanged lines hidden (view full) ---

3180 }
3181 }
3182 /* Checking if this TX ring missing TX completions have passed the threshold */
3183 if (unlikely(missed_tx > adapter->missing_tx_threshold)) {
3184 ena_log(pdev, ERR,
3185 "The number of lost tx completion is above the threshold "
3186 "(%d > %d). Reset the device\n",
3187 missed_tx, adapter->missing_tx_threshold);
3158 ena_trigger_reset(adapter, ENA_REGS_RESET_MISS_TX_CMPL);
3188 /* Set the reset flag to prevent ena_cleanup() from running */
3189 ENA_FLAG_SET_ATOMIC(ENA_FLAG_TRIGGER_RESET, adapter);
3190 /* Need to make sure that ENA_FLAG_TRIGGER_RESET is visible to ena_cleanup() and
3191 * that cleanup_running is visible to check_missing_comp_in_tx_queue() to
3192 * prevent the case of accessing CQ concurrently with check_cdesc_in_tx_cq()
3193 */
3194 mb();
3195 cleanup_scheduled = !!(atomic_load_16(&tx_ring->que->cleanup_task.ta_pending));
3196 cleanup_running = !!(atomic_load_8((&tx_ring->cleanup_running)));
3197 if (!(cleanup_scheduled || cleanup_running))
3198 reset_reason = check_cdesc_in_tx_cq(adapter, tx_ring);
3199
3200 adapter->reset_reason = reset_reason;
3159 rc = EIO;
3160 }
3161 /* Add the newly discovered missing TX completions */
3162 counter_u64_add(tx_ring->tx_stats.missing_tx_comp, new_missed_tx);
3163
3164 return (rc);
3165}
3166

--- 446 unchanged lines hidden (view full) ---

3613
3614static void
3615ena_reset_task(void *arg, int pending)
3616{
3617 struct ena_adapter *adapter = (struct ena_adapter *)arg;
3618
3619 ENA_LOCK_LOCK();
3620 if (likely(ENA_FLAG_ISSET(ENA_FLAG_TRIGGER_RESET, adapter))) {
3201 rc = EIO;
3202 }
3203 /* Add the newly discovered missing TX completions */
3204 counter_u64_add(tx_ring->tx_stats.missing_tx_comp, new_missed_tx);
3205
3206 return (rc);
3207}
3208

--- 446 unchanged lines hidden (view full) ---

3655
3656static void
3657ena_reset_task(void *arg, int pending)
3658{
3659 struct ena_adapter *adapter = (struct ena_adapter *)arg;
3660
3661 ENA_LOCK_LOCK();
3662 if (likely(ENA_FLAG_ISSET(ENA_FLAG_TRIGGER_RESET, adapter))) {
3663 ena_increment_reset_counter(adapter);
3621 ena_destroy_device(adapter, false);
3622 ena_restore_device(adapter);
3623
3624 ena_log(adapter->pdev, INFO,
3625 "Device reset completed successfully, Driver info: %s\n",
3626 ena_version);
3627 }
3628 ENA_LOCK_UNLOCK();

--- 513 unchanged lines hidden ---
3664 ena_destroy_device(adapter, false);
3665 ena_restore_device(adapter);
3666
3667 ena_log(adapter->pdev, INFO,
3668 "Device reset completed successfully, Driver info: %s\n",
3669 ena_version);
3670 }
3671 ENA_LOCK_UNLOCK();

--- 513 unchanged lines hidden ---