From bb76036b17df2fcf38982a1c403c4eed7b6af76e Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sat, 23 Sep 2023 10:17:26 +0200 Subject: [PATCH] drop some 6.5 patches --- ...fetch-sense-data-for-successful-comm.patch | 36 +- ...e-references-to-non-existing-error_h.patch | 925 ------------ ...er-queue-64-bit-statistics-where-nec.patch | 1333 ----------------- queue-6.5/series | 2 - 4 files changed, 16 insertions(+), 2280 deletions(-) delete mode 100644 queue-6.5/ata-libata-remove-references-to-non-existing-error_h.patch delete mode 100644 queue-6.5/net-stmmac-use-per-queue-64-bit-statistics-where-nec.patch diff --git a/queue-6.5/ata-libata-core-fetch-sense-data-for-successful-comm.patch b/queue-6.5/ata-libata-core-fetch-sense-data-for-successful-comm.patch index 11d4967f70f..db9f1d9821b 100644 --- a/queue-6.5/ata-libata-core-fetch-sense-data-for-successful-comm.patch +++ b/queue-6.5/ata-libata-core-fetch-sense-data-for-successful-comm.patch @@ -41,28 +41,24 @@ Fixes: 3ac873c76d79 ("ata: libata-core: fix when to fetch sense data for success Signed-off-by: Niklas Cassel Signed-off-by: Damien Le Moal Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman --- - drivers/ata/libata-core.c | 7 ++----- + drivers/ata/libata-core.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) -diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c -index c7a29c3ac6701..291e128f4d2b4 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c -@@ -4919,11 +4919,8 @@ void ata_qc_complete(struct ata_queued_cmd *qc) - * been aborted by the device due to a limit timeout using the policy - * 0xD. For these commands, invoke EH to get the command sense data. - */ -- if (qc->result_tf.status & ATA_SENSE && -- ((ata_is_ncq(qc->tf.protocol) && -- dev->flags & ATA_DFLAG_CDL_ENABLED) || -- (!ata_is_ncq(qc->tf.protocol) && -- ata_id_sense_reporting_enabled(dev->id)))) { -+ if (qc->flags & ATA_QCFLAG_HAS_CDL && -+ qc->result_tf.status & ATA_SENSE) { - /* - * Tell SCSI EH to not overwrite scmd->result even if this - * command is finished with result SAM_STAT_GOOD. --- -2.40.1 - +@@ -4935,11 +4935,8 @@ void ata_qc_complete(struct ata_queued_c + * timeout using the policy 0xD. For these commands, invoke EH + * to get the command sense data. + */ +- if (qc->result_tf.status & ATA_SENSE && +- ((ata_is_ncq(qc->tf.protocol) && +- dev->flags & ATA_DFLAG_CDL_ENABLED) || +- (!ata_is_ncq(qc->tf.protocol) && +- ata_id_sense_reporting_enabled(dev->id)))) { ++ if (qc->flags & ATA_QCFLAG_HAS_CDL && ++ qc->result_tf.status & ATA_SENSE) { + /* + * Tell SCSI EH to not overwrite scmd->result even if + * this command is finished with result SAM_STAT_GOOD. diff --git a/queue-6.5/ata-libata-remove-references-to-non-existing-error_h.patch b/queue-6.5/ata-libata-remove-references-to-non-existing-error_h.patch deleted file mode 100644 index 5fe5c33f540..00000000000 --- a/queue-6.5/ata-libata-remove-references-to-non-existing-error_h.patch +++ /dev/null @@ -1,925 +0,0 @@ -From 8df03fd2bc8c18590abf842bc2d997fb2972ceb4 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Mon, 31 Jul 2023 16:34:12 +0200 -Subject: ata: libata: remove references to non-existing error_handler() - -From: Hannes Reinecke - -[ Upstream commit ff8072d589dcff7c1f0345a6ec98b5fc1e9ee2a1 ] - -With commit 65a15d6560df ("scsi: ipr: Remove SATA support") all -libata drivers now have the error_handler() callback provided, -so we can stop checking for non-existing error_handler callback. - -Signed-off-by: Hannes Reinecke -[niklas: fixed review comments, rebased, solved conflicts during rebase, -fixed bug that unconditionally dumped all QCs, removed the now unused -function ata_dump_status(), removed the now unreachable failure paths in -atapi_qc_complete(), removed the non-EH function to request ATAPI sense] -Signed-off-by: Niklas Cassel -Reviewed-by: John Garry -Reviewed-by: Jason Yan -Reviewed-by: Martin K. Petersen -Signed-off-by: Damien Le Moal -Stable-dep-of: 5e35a9ac3fe3 ("ata: libata-core: fetch sense data for successful commands iff CDL enabled") -Signed-off-by: Sasha Levin ---- - drivers/ata/libata-core.c | 209 +++++++++++++++----------------------- - drivers/ata/libata-eh.c | 152 ++++++++++++--------------- - drivers/ata/libata-sata.c | 7 +- - drivers/ata/libata-scsi.c | 161 ++--------------------------- - drivers/ata/libata-sff.c | 30 ++---- - include/linux/libata.h | 2 +- - 6 files changed, 170 insertions(+), 391 deletions(-) - -diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c -index 04db0f2c683a7..c7a29c3ac6701 100644 ---- a/drivers/ata/libata-core.c -+++ b/drivers/ata/libata-core.c -@@ -1586,13 +1586,11 @@ static unsigned ata_exec_internal_sg(struct ata_device *dev, - } - } - -- if (ap->ops->error_handler) -- ata_eh_release(ap); -+ ata_eh_release(ap); - - rc = wait_for_completion_timeout(&wait, msecs_to_jiffies(timeout)); - -- if (ap->ops->error_handler) -- ata_eh_acquire(ap); -+ ata_eh_acquire(ap); - - ata_sff_flush_pio_task(ap); - -@@ -1607,10 +1605,7 @@ static unsigned ata_exec_internal_sg(struct ata_device *dev, - if (qc->flags & ATA_QCFLAG_ACTIVE) { - qc->err_mask |= AC_ERR_TIMEOUT; - -- if (ap->ops->error_handler) -- ata_port_freeze(ap); -- else -- ata_qc_complete(qc); -+ ata_port_freeze(ap); - - ata_dev_warn(dev, "qc timeout after %u msecs (cmd 0x%x)\n", - timeout, command); -@@ -4874,126 +4869,103 @@ static void ata_verify_xfer(struct ata_queued_cmd *qc) - void ata_qc_complete(struct ata_queued_cmd *qc) - { - struct ata_port *ap = qc->ap; -+ struct ata_device *dev = qc->dev; -+ struct ata_eh_info *ehi = &dev->link->eh_info; - - /* Trigger the LED (if available) */ - ledtrig_disk_activity(!!(qc->tf.flags & ATA_TFLAG_WRITE)); - -- /* XXX: New EH and old EH use different mechanisms to -- * synchronize EH with regular execution path. -- * -- * In new EH, a qc owned by EH is marked with ATA_QCFLAG_EH. -- * Normal execution path is responsible for not accessing a -- * qc owned by EH. libata core enforces the rule by returning NULL -- * from ata_qc_from_tag() for qcs owned by EH. -+ /* -+ * In order to synchronize EH with the regular execution path, a qc that -+ * is owned by EH is marked with ATA_QCFLAG_EH. - * -- * Old EH depends on ata_qc_complete() nullifying completion -- * requests if ATA_QCFLAG_EH_SCHEDULED is set. Old EH does -- * not synchronize with interrupt handler. Only PIO task is -- * taken care of. -+ * The normal execution path is responsible for not accessing a qc owned -+ * by EH. libata core enforces the rule by returning NULL from -+ * ata_qc_from_tag() for qcs owned by EH. - */ -- if (ap->ops->error_handler) { -- struct ata_device *dev = qc->dev; -- struct ata_eh_info *ehi = &dev->link->eh_info; -- -- if (unlikely(qc->err_mask)) -- qc->flags |= ATA_QCFLAG_EH; -+ if (unlikely(qc->err_mask)) -+ qc->flags |= ATA_QCFLAG_EH; - -- /* -- * Finish internal commands without any further processing -- * and always with the result TF filled. -- */ -- if (unlikely(ata_tag_internal(qc->tag))) { -- fill_result_tf(qc); -- trace_ata_qc_complete_internal(qc); -- __ata_qc_complete(qc); -- return; -- } -+ /* -+ * Finish internal commands without any further processing and always -+ * with the result TF filled. -+ */ -+ if (unlikely(ata_tag_internal(qc->tag))) { -+ fill_result_tf(qc); -+ trace_ata_qc_complete_internal(qc); -+ __ata_qc_complete(qc); -+ return; -+ } - -- /* -- * Non-internal qc has failed. Fill the result TF and -- * summon EH. -- */ -- if (unlikely(qc->flags & ATA_QCFLAG_EH)) { -- fill_result_tf(qc); -- trace_ata_qc_complete_failed(qc); -- ata_qc_schedule_eh(qc); -- return; -- } -+ /* Non-internal qc has failed. Fill the result TF and summon EH. */ -+ if (unlikely(qc->flags & ATA_QCFLAG_EH)) { -+ fill_result_tf(qc); -+ trace_ata_qc_complete_failed(qc); -+ ata_qc_schedule_eh(qc); -+ return; -+ } - -- WARN_ON_ONCE(ata_port_is_frozen(ap)); -+ WARN_ON_ONCE(ata_port_is_frozen(ap)); - -- /* read result TF if requested */ -- if (qc->flags & ATA_QCFLAG_RESULT_TF) -- fill_result_tf(qc); -+ /* read result TF if requested */ -+ if (qc->flags & ATA_QCFLAG_RESULT_TF) -+ fill_result_tf(qc); - -- trace_ata_qc_complete_done(qc); -+ trace_ata_qc_complete_done(qc); - -+ /* -+ * For CDL commands that completed without an error, check if we have -+ * sense data (ATA_SENSE is set). If we do, then the command may have -+ * been aborted by the device due to a limit timeout using the policy -+ * 0xD. For these commands, invoke EH to get the command sense data. -+ */ -+ if (qc->result_tf.status & ATA_SENSE && -+ ((ata_is_ncq(qc->tf.protocol) && -+ dev->flags & ATA_DFLAG_CDL_ENABLED) || -+ (!ata_is_ncq(qc->tf.protocol) && -+ ata_id_sense_reporting_enabled(dev->id)))) { - /* -- * For CDL commands that completed without an error, check if -- * we have sense data (ATA_SENSE is set). If we do, then the -- * command may have been aborted by the device due to a limit -- * timeout using the policy 0xD. For these commands, invoke EH -- * to get the command sense data. -+ * Tell SCSI EH to not overwrite scmd->result even if this -+ * command is finished with result SAM_STAT_GOOD. - */ -- if (qc->result_tf.status & ATA_SENSE && -- ((ata_is_ncq(qc->tf.protocol) && -- dev->flags & ATA_DFLAG_CDL_ENABLED) || -- (!ata_is_ncq(qc->tf.protocol) && -- ata_id_sense_reporting_enabled(dev->id)))) { -- /* -- * Tell SCSI EH to not overwrite scmd->result even if -- * this command is finished with result SAM_STAT_GOOD. -- */ -- qc->scsicmd->flags |= SCMD_FORCE_EH_SUCCESS; -- qc->flags |= ATA_QCFLAG_EH_SUCCESS_CMD; -- ehi->dev_action[dev->devno] |= ATA_EH_GET_SUCCESS_SENSE; -- -- /* -- * set pending so that ata_qc_schedule_eh() does not -- * trigger fast drain, and freeze the port. -- */ -- ap->pflags |= ATA_PFLAG_EH_PENDING; -- ata_qc_schedule_eh(qc); -- return; -- } -+ qc->scsicmd->flags |= SCMD_FORCE_EH_SUCCESS; -+ qc->flags |= ATA_QCFLAG_EH_SUCCESS_CMD; -+ ehi->dev_action[dev->devno] |= ATA_EH_GET_SUCCESS_SENSE; - -- /* Some commands need post-processing after successful -- * completion. -+ /* -+ * set pending so that ata_qc_schedule_eh() does not trigger -+ * fast drain, and freeze the port. - */ -- switch (qc->tf.command) { -- case ATA_CMD_SET_FEATURES: -- if (qc->tf.feature != SETFEATURES_WC_ON && -- qc->tf.feature != SETFEATURES_WC_OFF && -- qc->tf.feature != SETFEATURES_RA_ON && -- qc->tf.feature != SETFEATURES_RA_OFF) -- break; -- fallthrough; -- case ATA_CMD_INIT_DEV_PARAMS: /* CHS translation changed */ -- case ATA_CMD_SET_MULTI: /* multi_count changed */ -- /* revalidate device */ -- ehi->dev_action[dev->devno] |= ATA_EH_REVALIDATE; -- ata_port_schedule_eh(ap); -- break; -+ ap->pflags |= ATA_PFLAG_EH_PENDING; -+ ata_qc_schedule_eh(qc); -+ return; -+ } - -- case ATA_CMD_SLEEP: -- dev->flags |= ATA_DFLAG_SLEEPING; -+ /* Some commands need post-processing after successful completion. */ -+ switch (qc->tf.command) { -+ case ATA_CMD_SET_FEATURES: -+ if (qc->tf.feature != SETFEATURES_WC_ON && -+ qc->tf.feature != SETFEATURES_WC_OFF && -+ qc->tf.feature != SETFEATURES_RA_ON && -+ qc->tf.feature != SETFEATURES_RA_OFF) - break; -- } -- -- if (unlikely(dev->flags & ATA_DFLAG_DUBIOUS_XFER)) -- ata_verify_xfer(qc); -+ fallthrough; -+ case ATA_CMD_INIT_DEV_PARAMS: /* CHS translation changed */ -+ case ATA_CMD_SET_MULTI: /* multi_count changed */ -+ /* revalidate device */ -+ ehi->dev_action[dev->devno] |= ATA_EH_REVALIDATE; -+ ata_port_schedule_eh(ap); -+ break; - -- __ata_qc_complete(qc); -- } else { -- if (qc->flags & ATA_QCFLAG_EH_SCHEDULED) -- return; -+ case ATA_CMD_SLEEP: -+ dev->flags |= ATA_DFLAG_SLEEPING; -+ break; -+ } - -- /* read result TF if failed or requested */ -- if (qc->err_mask || qc->flags & ATA_QCFLAG_RESULT_TF) -- fill_result_tf(qc); -+ if (unlikely(dev->flags & ATA_DFLAG_DUBIOUS_XFER)) -+ ata_verify_xfer(qc); - -- __ata_qc_complete(qc); -- } -+ __ata_qc_complete(qc); - } - EXPORT_SYMBOL_GPL(ata_qc_complete); - -@@ -5039,11 +5011,8 @@ void ata_qc_issue(struct ata_queued_cmd *qc) - struct ata_link *link = qc->dev->link; - u8 prot = qc->tf.protocol; - -- /* Make sure only one non-NCQ command is outstanding. The -- * check is skipped for old EH because it reuses active qc to -- * request ATAPI sense. -- */ -- WARN_ON_ONCE(ap->ops->error_handler && ata_tag_valid(link->active_tag)); -+ /* Make sure only one non-NCQ command is outstanding. */ -+ WARN_ON_ONCE(ata_tag_valid(link->active_tag)); - - if (ata_is_ncq(prot)) { - WARN_ON_ONCE(link->sactive & (1 << qc->hw_tag)); -@@ -5917,15 +5886,9 @@ void __ata_port_probe(struct ata_port *ap) - - int ata_port_probe(struct ata_port *ap) - { -- int rc = 0; -- -- if (ap->ops->error_handler) { -- __ata_port_probe(ap); -- ata_port_wait_eh(ap); -- } else { -- rc = ata_bus_probe(ap); -- } -- return rc; -+ __ata_port_probe(ap); -+ ata_port_wait_eh(ap); -+ return 0; - } - - -@@ -6130,9 +6093,6 @@ static void ata_port_detach(struct ata_port *ap) - struct ata_link *link; - struct ata_device *dev; - -- if (!ap->ops->error_handler) -- goto skip_eh; -- - /* tell EH we're leaving & flush EH */ - spin_lock_irqsave(ap->lock, flags); - ap->pflags |= ATA_PFLAG_UNLOADING; -@@ -6148,7 +6108,6 @@ static void ata_port_detach(struct ata_port *ap) - cancel_delayed_work_sync(&ap->hotplug_task); - cancel_delayed_work_sync(&ap->scsi_rescan_task); - -- skip_eh: - /* clean up zpodd on port removal */ - ata_for_each_link(link, ap, HOST_FIRST) { - ata_for_each_dev(dev, link, ALL) { -diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c -index 35e03679b0bfe..9d6affabf225a 100644 ---- a/drivers/ata/libata-eh.c -+++ b/drivers/ata/libata-eh.c -@@ -571,13 +571,10 @@ void ata_scsi_cmd_error_handler(struct Scsi_Host *host, struct ata_port *ap, - /* make sure sff pio task is not running */ - ata_sff_flush_pio_task(ap); - -- if (!ap->ops->error_handler) -- return; -- - /* synchronize with host lock and sort out timeouts */ - - /* -- * For new EH, all qcs are finished in one of three ways - -+ * For EH, all qcs are finished in one of three ways - - * normal completion, error completion, and SCSI timeout. - * Both completions can race against SCSI timeout. When normal - * completion wins, the qc never reaches EH. When error -@@ -659,94 +656,87 @@ EXPORT_SYMBOL(ata_scsi_cmd_error_handler); - void ata_scsi_port_error_handler(struct Scsi_Host *host, struct ata_port *ap) - { - unsigned long flags; -+ struct ata_link *link; - -- /* invoke error handler */ -- if (ap->ops->error_handler) { -- struct ata_link *link; -- -- /* acquire EH ownership */ -- ata_eh_acquire(ap); -+ /* acquire EH ownership */ -+ ata_eh_acquire(ap); - repeat: -- /* kill fast drain timer */ -- del_timer_sync(&ap->fastdrain_timer); -+ /* kill fast drain timer */ -+ del_timer_sync(&ap->fastdrain_timer); - -- /* process port resume request */ -- ata_eh_handle_port_resume(ap); -+ /* process port resume request */ -+ ata_eh_handle_port_resume(ap); - -- /* fetch & clear EH info */ -- spin_lock_irqsave(ap->lock, flags); -+ /* fetch & clear EH info */ -+ spin_lock_irqsave(ap->lock, flags); - -- ata_for_each_link(link, ap, HOST_FIRST) { -- struct ata_eh_context *ehc = &link->eh_context; -- struct ata_device *dev; -+ ata_for_each_link(link, ap, HOST_FIRST) { -+ struct ata_eh_context *ehc = &link->eh_context; -+ struct ata_device *dev; - -- memset(&link->eh_context, 0, sizeof(link->eh_context)); -- link->eh_context.i = link->eh_info; -- memset(&link->eh_info, 0, sizeof(link->eh_info)); -+ memset(&link->eh_context, 0, sizeof(link->eh_context)); -+ link->eh_context.i = link->eh_info; -+ memset(&link->eh_info, 0, sizeof(link->eh_info)); - -- ata_for_each_dev(dev, link, ENABLED) { -- int devno = dev->devno; -+ ata_for_each_dev(dev, link, ENABLED) { -+ int devno = dev->devno; - -- ehc->saved_xfer_mode[devno] = dev->xfer_mode; -- if (ata_ncq_enabled(dev)) -- ehc->saved_ncq_enabled |= 1 << devno; -- } -+ ehc->saved_xfer_mode[devno] = dev->xfer_mode; -+ if (ata_ncq_enabled(dev)) -+ ehc->saved_ncq_enabled |= 1 << devno; - } -+ } - -- ap->pflags |= ATA_PFLAG_EH_IN_PROGRESS; -- ap->pflags &= ~ATA_PFLAG_EH_PENDING; -- ap->excl_link = NULL; /* don't maintain exclusion over EH */ -+ ap->pflags |= ATA_PFLAG_EH_IN_PROGRESS; -+ ap->pflags &= ~ATA_PFLAG_EH_PENDING; -+ ap->excl_link = NULL; /* don't maintain exclusion over EH */ - -- spin_unlock_irqrestore(ap->lock, flags); -+ spin_unlock_irqrestore(ap->lock, flags); - -- /* invoke EH, skip if unloading or suspended */ -- if (!(ap->pflags & (ATA_PFLAG_UNLOADING | ATA_PFLAG_SUSPENDED))) -- ap->ops->error_handler(ap); -- else { -- /* if unloading, commence suicide */ -- if ((ap->pflags & ATA_PFLAG_UNLOADING) && -- !(ap->pflags & ATA_PFLAG_UNLOADED)) -- ata_eh_unload(ap); -- ata_eh_finish(ap); -- } -+ /* invoke EH, skip if unloading or suspended */ -+ if (!(ap->pflags & (ATA_PFLAG_UNLOADING | ATA_PFLAG_SUSPENDED))) -+ ap->ops->error_handler(ap); -+ else { -+ /* if unloading, commence suicide */ -+ if ((ap->pflags & ATA_PFLAG_UNLOADING) && -+ !(ap->pflags & ATA_PFLAG_UNLOADED)) -+ ata_eh_unload(ap); -+ ata_eh_finish(ap); -+ } - -- /* process port suspend request */ -- ata_eh_handle_port_suspend(ap); -+ /* process port suspend request */ -+ ata_eh_handle_port_suspend(ap); - -- /* Exception might have happened after ->error_handler -- * recovered the port but before this point. Repeat -- * EH in such case. -- */ -- spin_lock_irqsave(ap->lock, flags); -+ /* -+ * Exception might have happened after ->error_handler recovered the -+ * port but before this point. Repeat EH in such case. -+ */ -+ spin_lock_irqsave(ap->lock, flags); - -- if (ap->pflags & ATA_PFLAG_EH_PENDING) { -- if (--ap->eh_tries) { -- spin_unlock_irqrestore(ap->lock, flags); -- goto repeat; -- } -- ata_port_err(ap, -- "EH pending after %d tries, giving up\n", -- ATA_EH_MAX_TRIES); -- ap->pflags &= ~ATA_PFLAG_EH_PENDING; -+ if (ap->pflags & ATA_PFLAG_EH_PENDING) { -+ if (--ap->eh_tries) { -+ spin_unlock_irqrestore(ap->lock, flags); -+ goto repeat; - } -+ ata_port_err(ap, -+ "EH pending after %d tries, giving up\n", -+ ATA_EH_MAX_TRIES); -+ ap->pflags &= ~ATA_PFLAG_EH_PENDING; -+ } - -- /* this run is complete, make sure EH info is clear */ -- ata_for_each_link(link, ap, HOST_FIRST) -- memset(&link->eh_info, 0, sizeof(link->eh_info)); -+ /* this run is complete, make sure EH info is clear */ -+ ata_for_each_link(link, ap, HOST_FIRST) -+ memset(&link->eh_info, 0, sizeof(link->eh_info)); - -- /* end eh (clear host_eh_scheduled) while holding -- * ap->lock such that if exception occurs after this -- * point but before EH completion, SCSI midlayer will -- * re-initiate EH. -- */ -- ap->ops->end_eh(ap); -+ /* -+ * end eh (clear host_eh_scheduled) while holding ap->lock such that if -+ * exception occurs after this point but before EH completion, SCSI -+ * midlayer will re-initiate EH. -+ */ -+ ap->ops->end_eh(ap); - -- spin_unlock_irqrestore(ap->lock, flags); -- ata_eh_release(ap); -- } else { -- WARN_ON(ata_qc_from_tag(ap, ap->link.active_tag) == NULL); -- ap->ops->eng_timeout(ap); -- } -+ spin_unlock_irqrestore(ap->lock, flags); -+ ata_eh_release(ap); - - scsi_eh_flush_done_q(&ap->eh_done_q); - -@@ -912,8 +902,6 @@ void ata_qc_schedule_eh(struct ata_queued_cmd *qc) - { - struct ata_port *ap = qc->ap; - -- WARN_ON(!ap->ops->error_handler); -- - qc->flags |= ATA_QCFLAG_EH; - ata_eh_set_pending(ap, 1); - -@@ -934,8 +922,6 @@ void ata_qc_schedule_eh(struct ata_queued_cmd *qc) - */ - void ata_std_sched_eh(struct ata_port *ap) - { -- WARN_ON(!ap->ops->error_handler); -- - if (ap->pflags & ATA_PFLAG_INITIALIZING) - return; - -@@ -989,8 +975,6 @@ static int ata_do_link_abort(struct ata_port *ap, struct ata_link *link) - struct ata_queued_cmd *qc; - int tag, nr_aborted = 0; - -- WARN_ON(!ap->ops->error_handler); -- - /* we're gonna abort all commands, no need for fast drain */ - ata_eh_set_pending(ap, 0); - -@@ -1065,8 +1049,6 @@ EXPORT_SYMBOL_GPL(ata_port_abort); - */ - static void __ata_port_freeze(struct ata_port *ap) - { -- WARN_ON(!ap->ops->error_handler); -- - if (ap->ops->freeze) - ap->ops->freeze(ap); - -@@ -1091,8 +1073,6 @@ static void __ata_port_freeze(struct ata_port *ap) - */ - int ata_port_freeze(struct ata_port *ap) - { -- WARN_ON(!ap->ops->error_handler); -- - __ata_port_freeze(ap); - - return ata_port_abort(ap); -@@ -1112,9 +1092,6 @@ void ata_eh_freeze_port(struct ata_port *ap) - { - unsigned long flags; - -- if (!ap->ops->error_handler) -- return; -- - spin_lock_irqsave(ap->lock, flags); - __ata_port_freeze(ap); - spin_unlock_irqrestore(ap->lock, flags); -@@ -1134,9 +1111,6 @@ void ata_eh_thaw_port(struct ata_port *ap) - { - unsigned long flags; - -- if (!ap->ops->error_handler) -- return; -- - spin_lock_irqsave(ap->lock, flags); - - ap->pflags &= ~ATA_PFLAG_FROZEN; -diff --git a/drivers/ata/libata-sata.c b/drivers/ata/libata-sata.c -index 85e279a12f62c..99d4ab04bcce6 100644 ---- a/drivers/ata/libata-sata.c -+++ b/drivers/ata/libata-sata.c -@@ -1158,12 +1158,7 @@ EXPORT_SYMBOL_GPL(ata_sas_port_alloc); - */ - int ata_sas_port_start(struct ata_port *ap) - { -- /* -- * the port is marked as frozen at allocation time, but if we don't -- * have new eh, we won't thaw it -- */ -- if (!ap->ops->error_handler) -- ap->pflags &= ~ATA_PFLAG_FROZEN; -+ /* the port is marked as frozen at allocation time */ - return 0; - } - EXPORT_SYMBOL_GPL(ata_sas_port_start); -diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c -index c6ece32de8e31..e55db9a6826f3 100644 ---- a/drivers/ata/libata-scsi.c -+++ b/drivers/ata/libata-scsi.c -@@ -709,47 +709,6 @@ static void ata_qc_set_pc_nbytes(struct ata_queued_cmd *qc) - qc->nbytes = scsi_bufflen(scmd) + qc->extrabytes; - } - --/** -- * ata_dump_status - user friendly display of error info -- * @ap: the port in question -- * @tf: ptr to filled out taskfile -- * -- * Decode and dump the ATA error/status registers for the user so -- * that they have some idea what really happened at the non -- * make-believe layer. -- * -- * LOCKING: -- * inherited from caller -- */ --static void ata_dump_status(struct ata_port *ap, struct ata_taskfile *tf) --{ -- u8 stat = tf->status, err = tf->error; -- -- if (stat & ATA_BUSY) { -- ata_port_warn(ap, "status=0x%02x {Busy} ", stat); -- } else { -- ata_port_warn(ap, "status=0x%02x { %s%s%s%s%s%s%s} ", stat, -- stat & ATA_DRDY ? "DriveReady " : "", -- stat & ATA_DF ? "DeviceFault " : "", -- stat & ATA_DSC ? "SeekComplete " : "", -- stat & ATA_DRQ ? "DataRequest " : "", -- stat & ATA_CORR ? "CorrectedError " : "", -- stat & ATA_SENSE ? "Sense " : "", -- stat & ATA_ERR ? "Error " : ""); -- if (err) -- ata_port_warn(ap, "error=0x%02x {%s%s%s%s%s%s", err, -- err & ATA_ABORTED ? -- "DriveStatusError " : "", -- err & ATA_ICRC ? -- (err & ATA_ABORTED ? -- "BadCRC " : "Sector ") : "", -- err & ATA_UNC ? "UncorrectableError " : "", -- err & ATA_IDNF ? "SectorIdNotFound " : "", -- err & ATA_TRK0NF ? "TrackZeroNotFound " : "", -- err & ATA_AMNF ? "AddrMarkNotFound " : ""); -- } --} -- - /** - * ata_to_sense_error - convert ATA error to SCSI error - * @id: ATA device number -@@ -758,7 +717,6 @@ static void ata_dump_status(struct ata_port *ap, struct ata_taskfile *tf) - * @sk: the sense key we'll fill out - * @asc: the additional sense code we'll fill out - * @ascq: the additional sense code qualifier we'll fill out -- * @verbose: be verbose - * - * Converts an ATA error into a SCSI error. Fill out pointers to - * SK, ASC, and ASCQ bytes for later use in fixed or descriptor -@@ -768,7 +726,7 @@ static void ata_dump_status(struct ata_port *ap, struct ata_taskfile *tf) - * spin_lock_irqsave(host lock) - */ - static void ata_to_sense_error(unsigned id, u8 drv_stat, u8 drv_err, u8 *sk, -- u8 *asc, u8 *ascq, int verbose) -+ u8 *asc, u8 *ascq) - { - int i; - -@@ -847,7 +805,7 @@ static void ata_to_sense_error(unsigned id, u8 drv_stat, u8 drv_err, u8 *sk, - *sk = sense_table[i][1]; - *asc = sense_table[i][2]; - *ascq = sense_table[i][3]; -- goto translate_done; -+ return; - } - } - } -@@ -862,7 +820,7 @@ static void ata_to_sense_error(unsigned id, u8 drv_stat, u8 drv_err, u8 *sk, - *sk = stat_table[i][1]; - *asc = stat_table[i][2]; - *ascq = stat_table[i][3]; -- goto translate_done; -+ return; - } - } - -@@ -873,12 +831,6 @@ static void ata_to_sense_error(unsigned id, u8 drv_stat, u8 drv_err, u8 *sk, - *sk = ABORTED_COMMAND; - *asc = 0x00; - *ascq = 0x00; -- -- translate_done: -- if (verbose) -- pr_err("ata%u: translated ATA stat/err 0x%02x/%02x to SCSI SK/ASC/ASCQ 0x%x/%02x/%02x\n", -- id, drv_stat, drv_err, *sk, *asc, *ascq); -- return; - } - - /* -@@ -904,7 +856,6 @@ static void ata_gen_passthru_sense(struct ata_queued_cmd *qc) - struct ata_taskfile *tf = &qc->result_tf; - unsigned char *sb = cmd->sense_buffer; - unsigned char *desc = sb + 8; -- int verbose = qc->ap->ops->error_handler == NULL; - u8 sense_key, asc, ascq; - - memset(sb, 0, SCSI_SENSE_BUFFERSIZE); -@@ -916,7 +867,7 @@ static void ata_gen_passthru_sense(struct ata_queued_cmd *qc) - if (qc->err_mask || - tf->status & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) { - ata_to_sense_error(qc->ap->print_id, tf->status, tf->error, -- &sense_key, &asc, &ascq, verbose); -+ &sense_key, &asc, &ascq); - ata_scsi_set_sense(qc->dev, cmd, sense_key, asc, ascq); - } else { - /* -@@ -999,7 +950,6 @@ static void ata_gen_ata_sense(struct ata_queued_cmd *qc) - struct scsi_cmnd *cmd = qc->scsicmd; - struct ata_taskfile *tf = &qc->result_tf; - unsigned char *sb = cmd->sense_buffer; -- int verbose = qc->ap->ops->error_handler == NULL; - u64 block; - u8 sense_key, asc, ascq; - -@@ -1017,7 +967,7 @@ static void ata_gen_ata_sense(struct ata_queued_cmd *qc) - if (qc->err_mask || - tf->status & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) { - ata_to_sense_error(qc->ap->print_id, tf->status, tf->error, -- &sense_key, &asc, &ascq, verbose); -+ &sense_key, &asc, &ascq); - ata_scsi_set_sense(dev, cmd, sense_key, asc, ascq); - } else { - /* Could not decode error */ -@@ -1186,9 +1136,6 @@ void ata_scsi_slave_destroy(struct scsi_device *sdev) - unsigned long flags; - struct ata_device *dev; - -- if (!ap->ops->error_handler) -- return; -- - spin_lock_irqsave(ap->lock, flags); - dev = __ata_scsi_find_dev(ap, sdev); - if (dev && dev->sdev) { -@@ -1675,7 +1622,6 @@ static void ata_qc_done(struct ata_queued_cmd *qc) - - static void ata_scsi_qc_complete(struct ata_queued_cmd *qc) - { -- struct ata_port *ap = qc->ap; - struct scsi_cmnd *cmd = qc->scsicmd; - u8 *cdb = cmd->cmnd; - int need_sense = (qc->err_mask != 0) && -@@ -1699,9 +1645,6 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc) - /* Keep the SCSI ML and status byte, clear host byte. */ - cmd->result &= 0x0000ffff; - -- if (need_sense && !ap->ops->error_handler) -- ata_dump_status(ap, &qc->result_tf); -- - ata_qc_done(qc); - } - -@@ -2608,71 +2551,6 @@ static unsigned int ata_scsiop_report_luns(struct ata_scsi_args *args, u8 *rbuf) - return 0; - } - --static void atapi_sense_complete(struct ata_queued_cmd *qc) --{ -- if (qc->err_mask && ((qc->err_mask & AC_ERR_DEV) == 0)) { -- /* FIXME: not quite right; we don't want the -- * translation of taskfile registers into -- * a sense descriptors, since that's only -- * correct for ATA, not ATAPI -- */ -- ata_gen_passthru_sense(qc); -- } -- -- ata_qc_done(qc); --} -- --/* is it pointless to prefer PIO for "safety reasons"? */ --static inline int ata_pio_use_silly(struct ata_port *ap) --{ -- return (ap->flags & ATA_FLAG_PIO_DMA); --} -- --static void atapi_request_sense(struct ata_queued_cmd *qc) --{ -- struct ata_port *ap = qc->ap; -- struct scsi_cmnd *cmd = qc->scsicmd; -- -- memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); -- --#ifdef CONFIG_ATA_SFF -- if (ap->ops->sff_tf_read) -- ap->ops->sff_tf_read(ap, &qc->tf); --#endif -- -- /* fill these in, for the case where they are -not- overwritten */ -- cmd->sense_buffer[0] = 0x70; -- cmd->sense_buffer[2] = qc->tf.error >> 4; -- -- ata_qc_reinit(qc); -- -- /* setup sg table and init transfer direction */ -- sg_init_one(&qc->sgent, cmd->sense_buffer, SCSI_SENSE_BUFFERSIZE); -- ata_sg_init(qc, &qc->sgent, 1); -- qc->dma_dir = DMA_FROM_DEVICE; -- -- memset(&qc->cdb, 0, qc->dev->cdb_len); -- qc->cdb[0] = REQUEST_SENSE; -- qc->cdb[4] = SCSI_SENSE_BUFFERSIZE; -- -- qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; -- qc->tf.command = ATA_CMD_PACKET; -- -- if (ata_pio_use_silly(ap)) { -- qc->tf.protocol = ATAPI_PROT_DMA; -- qc->tf.feature |= ATAPI_PKT_DMA; -- } else { -- qc->tf.protocol = ATAPI_PROT_PIO; -- qc->tf.lbam = SCSI_SENSE_BUFFERSIZE; -- qc->tf.lbah = 0; -- } -- qc->nbytes = SCSI_SENSE_BUFFERSIZE; -- -- qc->complete_fn = atapi_sense_complete; -- -- ata_qc_issue(qc); --} -- - /* - * ATAPI devices typically report zero for their SCSI version, and sometimes - * deviate from the spec WRT response data format. If SCSI version is -@@ -2698,9 +2576,8 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc) - struct scsi_cmnd *cmd = qc->scsicmd; - unsigned int err_mask = qc->err_mask; - -- /* handle completion from new EH */ -- if (unlikely(qc->ap->ops->error_handler && -- (err_mask || qc->flags & ATA_QCFLAG_SENSE_VALID))) { -+ /* handle completion from EH */ -+ if (unlikely(err_mask || qc->flags & ATA_QCFLAG_SENSE_VALID)) { - - if (!(qc->flags & ATA_QCFLAG_SENSE_VALID)) { - /* FIXME: not quite right; we don't want the -@@ -2732,23 +2609,10 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc) - return; - } - -- /* successful completion or old EH failure path */ -- if (unlikely(err_mask & AC_ERR_DEV)) { -- cmd->result = SAM_STAT_CHECK_CONDITION; -- atapi_request_sense(qc); -- return; -- } else if (unlikely(err_mask)) { -- /* FIXME: not quite right; we don't want the -- * translation of taskfile registers into -- * a sense descriptors, since that's only -- * correct for ATA, not ATAPI -- */ -- ata_gen_passthru_sense(qc); -- } else { -- if (cmd->cmnd[0] == INQUIRY && (cmd->cmnd[1] & 0x03) == 0) -- atapi_fixup_inquiry(cmd); -- cmd->result = SAM_STAT_GOOD; -- } -+ /* successful completion path */ -+ if (cmd->cmnd[0] == INQUIRY && (cmd->cmnd[1] & 0x03) == 0) -+ atapi_fixup_inquiry(cmd); -+ cmd->result = SAM_STAT_GOOD; - - ata_qc_done(qc); - } -@@ -4797,9 +4661,6 @@ int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel, - unsigned long flags; - int devno, rc = 0; - -- if (!ap->ops->error_handler) -- return -EOPNOTSUPP; -- - if (lun != SCAN_WILD_CARD && lun) - return -EINVAL; - -diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c -index 9d28badfe41d6..84471d92cd1b9 100644 ---- a/drivers/ata/libata-sff.c -+++ b/drivers/ata/libata-sff.c -@@ -883,31 +883,21 @@ static void ata_hsm_qc_complete(struct ata_queued_cmd *qc, int in_wq) - { - struct ata_port *ap = qc->ap; - -- if (ap->ops->error_handler) { -- if (in_wq) { -- /* EH might have kicked in while host lock is -- * released. -- */ -- qc = ata_qc_from_tag(ap, qc->tag); -- if (qc) { -- if (likely(!(qc->err_mask & AC_ERR_HSM))) { -- ata_sff_irq_on(ap); -- ata_qc_complete(qc); -- } else -- ata_port_freeze(ap); -- } -- } else { -- if (likely(!(qc->err_mask & AC_ERR_HSM))) -+ if (in_wq) { -+ /* EH might have kicked in while host lock is released. */ -+ qc = ata_qc_from_tag(ap, qc->tag); -+ if (qc) { -+ if (likely(!(qc->err_mask & AC_ERR_HSM))) { -+ ata_sff_irq_on(ap); - ata_qc_complete(qc); -- else -+ } else - ata_port_freeze(ap); - } - } else { -- if (in_wq) { -- ata_sff_irq_on(ap); -- ata_qc_complete(qc); -- } else -+ if (likely(!(qc->err_mask & AC_ERR_HSM))) - ata_qc_complete(qc); -+ else -+ ata_port_freeze(ap); - } - } - -diff --git a/include/linux/libata.h b/include/linux/libata.h -index 820f7a3a2749b..3eeea76c30de4 100644 ---- a/include/linux/libata.h -+++ b/include/linux/libata.h -@@ -1785,7 +1785,7 @@ static inline struct ata_queued_cmd *ata_qc_from_tag(struct ata_port *ap, - { - struct ata_queued_cmd *qc = __ata_qc_from_tag(ap, tag); - -- if (unlikely(!qc) || !ap->ops->error_handler) -+ if (unlikely(!qc)) - return qc; - - if ((qc->flags & (ATA_QCFLAG_ACTIVE | --- -2.40.1 - diff --git a/queue-6.5/net-stmmac-use-per-queue-64-bit-statistics-where-nec.patch b/queue-6.5/net-stmmac-use-per-queue-64-bit-statistics-where-nec.patch deleted file mode 100644 index f2f0228296f..00000000000 --- a/queue-6.5/net-stmmac-use-per-queue-64-bit-statistics-where-nec.patch +++ /dev/null @@ -1,1333 +0,0 @@ -From 9c9cd57351a2f9c85963dce9d5185a261237b2d3 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Tue, 18 Jul 2023 00:06:30 +0800 -Subject: net: stmmac: use per-queue 64 bit statistics where necessary - -From: Jisheng Zhang - -[ Upstream commit 133466c3bbe171f826294161db203f7670bb30c8 ] - -Currently, there are two major issues with stmmac driver statistics -First of all, statistics in stmmac_extra_stats, stmmac_rxq_stats -and stmmac_txq_stats are 32 bit variables on 32 bit platforms. This -can cause some stats to overflow after several minutes of -high traffic, for example rx_pkt_n, tx_pkt_n and so on. - -Secondly, if HW supports multiqueues, there are frequent cacheline -ping pongs on some driver statistic vars, for example, normal_irq_n, -tx_pkt_n and so on. What's more, frequent cacheline ping pongs on -normal_irq_n happens in ISR, this makes the situation worse. - -To improve the driver, we convert those statistics to 64 bit, implement -ndo_get_stats64 and update .get_ethtool_stats implementation -accordingly. We also use per-queue statistics where necessary to remove -the cacheline ping pongs as much as possible to make multiqueue -operations faster. Those statistics which are not possible to overflow -and not frequently updated are kept as is. - -Signed-off-by: Jisheng Zhang -Link: https://lore.kernel.org/r/20230717160630.1892-3-jszhang@kernel.org -Signed-off-by: Jakub Kicinski -Signed-off-by: Sasha Levin ---- - drivers/net/ethernet/stmicro/stmmac/common.h | 39 ++-- - .../net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 12 +- - .../ethernet/stmicro/stmmac/dwmac100_dma.c | 7 +- - .../ethernet/stmicro/stmmac/dwmac4_descs.c | 16 +- - .../net/ethernet/stmicro/stmmac/dwmac4_lib.c | 15 +- - .../net/ethernet/stmicro/stmmac/dwmac_lib.c | 12 +- - .../ethernet/stmicro/stmmac/dwxgmac2_descs.c | 6 +- - .../ethernet/stmicro/stmmac/dwxgmac2_dma.c | 14 +- - .../net/ethernet/stmicro/stmmac/enh_desc.c | 20 +- - drivers/net/ethernet/stmicro/stmmac/hwif.h | 12 +- - .../net/ethernet/stmicro/stmmac/norm_desc.c | 15 +- - drivers/net/ethernet/stmicro/stmmac/stmmac.h | 2 + - .../ethernet/stmicro/stmmac/stmmac_ethtool.c | 123 ++++++++--- - .../net/ethernet/stmicro/stmmac/stmmac_main.c | 200 ++++++++++++++---- - 14 files changed, 335 insertions(+), 158 deletions(-) - -diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h -index 16e67c18b6f71..57f2137bbe9d9 100644 ---- a/drivers/net/ethernet/stmicro/stmmac/common.h -+++ b/drivers/net/ethernet/stmicro/stmmac/common.h -@@ -59,13 +59,25 @@ - /* #define FRAME_FILTER_DEBUG */ - - struct stmmac_txq_stats { -- unsigned long tx_pkt_n; -- unsigned long tx_normal_irq_n; -+ u64 tx_bytes; -+ u64 tx_packets; -+ u64 tx_pkt_n; -+ u64 tx_normal_irq_n; -+ u64 napi_poll; -+ u64 tx_clean; -+ u64 tx_set_ic_bit; -+ u64 tx_tso_frames; -+ u64 tx_tso_nfrags; -+ struct u64_stats_sync syncp; - }; - - struct stmmac_rxq_stats { -- unsigned long rx_pkt_n; -- unsigned long rx_normal_irq_n; -+ u64 rx_bytes; -+ u64 rx_packets; -+ u64 rx_pkt_n; -+ u64 rx_normal_irq_n; -+ u64 napi_poll; -+ struct u64_stats_sync syncp; - }; - - /* Extra statistic and debug information exposed by ethtool */ -@@ -81,6 +93,7 @@ struct stmmac_extra_stats { - unsigned long tx_frame_flushed; - unsigned long tx_payload_error; - unsigned long tx_ip_header_error; -+ unsigned long tx_collision; - /* Receive errors */ - unsigned long rx_desc; - unsigned long sa_filter_fail; -@@ -113,14 +126,6 @@ struct stmmac_extra_stats { - /* Tx/Rx IRQ Events */ - unsigned long rx_early_irq; - unsigned long threshold; -- unsigned long tx_pkt_n; -- unsigned long rx_pkt_n; -- unsigned long normal_irq_n; -- unsigned long rx_normal_irq_n; -- unsigned long napi_poll; -- unsigned long tx_normal_irq_n; -- unsigned long tx_clean; -- unsigned long tx_set_ic_bit; - unsigned long irq_receive_pmt_irq_n; - /* MMC info */ - unsigned long mmc_tx_irq_n; -@@ -190,18 +195,16 @@ struct stmmac_extra_stats { - unsigned long mtl_rx_fifo_ctrl_active; - unsigned long mac_rx_frame_ctrl_fifo; - unsigned long mac_gmii_rx_proto_engine; -- /* TSO */ -- unsigned long tx_tso_frames; -- unsigned long tx_tso_nfrags; - /* EST */ - unsigned long mtl_est_cgce; - unsigned long mtl_est_hlbs; - unsigned long mtl_est_hlbf; - unsigned long mtl_est_btre; - unsigned long mtl_est_btrlm; -- /* per queue statistics */ -- struct stmmac_txq_stats txq_stats[MTL_MAX_TX_QUEUES]; -- struct stmmac_rxq_stats rxq_stats[MTL_MAX_RX_QUEUES]; -+ unsigned long rx_dropped; -+ unsigned long rx_errors; -+ unsigned long tx_dropped; -+ unsigned long tx_errors; - }; - - /* Safety Feature statistics exposed by ethtool */ -diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c -index 1e714380d1250..b20f8ba34efd9 100644 ---- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c -+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c -@@ -440,8 +440,10 @@ static int sun8i_dwmac_dma_interrupt(struct stmmac_priv *priv, - struct stmmac_extra_stats *x, u32 chan, - u32 dir) - { -- u32 v; -+ struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[chan]; -+ struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[chan]; - int ret = 0; -+ u32 v; - - v = readl(ioaddr + EMAC_INT_STA); - -@@ -452,7 +454,9 @@ static int sun8i_dwmac_dma_interrupt(struct stmmac_priv *priv, - - if (v & EMAC_TX_INT) { - ret |= handle_tx; -- x->tx_normal_irq_n++; -+ u64_stats_update_begin(&tx_q->txq_stats.syncp); -+ tx_q->txq_stats.tx_normal_irq_n++; -+ u64_stats_update_end(&tx_q->txq_stats.syncp); - } - - if (v & EMAC_TX_DMA_STOP_INT) -@@ -474,7 +478,9 @@ static int sun8i_dwmac_dma_interrupt(struct stmmac_priv *priv, - - if (v & EMAC_RX_INT) { - ret |= handle_rx; -- x->rx_normal_irq_n++; -+ u64_stats_update_begin(&rx_q->rxq_stats.syncp); -+ rx_q->rxq_stats.rx_normal_irq_n++; -+ u64_stats_update_end(&rx_q->rxq_stats.syncp); - } - - if (v & EMAC_RX_BUF_UA_INT) -diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c -index 1c32b1788f02e..dea270f60cc3e 100644 ---- a/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c -+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c -@@ -82,29 +82,24 @@ static void dwmac100_dump_dma_regs(struct stmmac_priv *priv, - } - - /* DMA controller has two counters to track the number of the missed frames. */ --static void dwmac100_dma_diagnostic_fr(struct net_device_stats *stats, -- struct stmmac_extra_stats *x, -+static void dwmac100_dma_diagnostic_fr(struct stmmac_extra_stats *x, - void __iomem *ioaddr) - { - u32 csr8 = readl(ioaddr + DMA_MISSED_FRAME_CTR); - - if (unlikely(csr8)) { - if (csr8 & DMA_MISSED_FRAME_OVE) { -- stats->rx_over_errors += 0x800; - x->rx_overflow_cntr += 0x800; - } else { - unsigned int ove_cntr; - ove_cntr = ((csr8 & DMA_MISSED_FRAME_OVE_CNTR) >> 17); -- stats->rx_over_errors += ove_cntr; - x->rx_overflow_cntr += ove_cntr; - } - - if (csr8 & DMA_MISSED_FRAME_OVE_M) { -- stats->rx_missed_errors += 0xffff; - x->rx_missed_cntr += 0xffff; - } else { - unsigned int miss_f = (csr8 & DMA_MISSED_FRAME_M_CNTR); -- stats->rx_missed_errors += miss_f; - x->rx_missed_cntr += miss_f; - } - } -diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c -index 6a011d8633e8e..89a14084c6117 100644 ---- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c -+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c -@@ -13,8 +13,7 @@ - #include "dwmac4.h" - #include "dwmac4_descs.h" - --static int dwmac4_wrback_get_tx_status(struct net_device_stats *stats, -- struct stmmac_extra_stats *x, -+static int dwmac4_wrback_get_tx_status(struct stmmac_extra_stats *x, - struct dma_desc *p, - void __iomem *ioaddr) - { -@@ -40,15 +39,13 @@ static int dwmac4_wrback_get_tx_status(struct net_device_stats *stats, - x->tx_frame_flushed++; - if (unlikely(tdes3 & TDES3_LOSS_CARRIER)) { - x->tx_losscarrier++; -- stats->tx_carrier_errors++; - } - if (unlikely(tdes3 & TDES3_NO_CARRIER)) { - x->tx_carrier++; -- stats->tx_carrier_errors++; - } - if (unlikely((tdes3 & TDES3_LATE_COLLISION) || - (tdes3 & TDES3_EXCESSIVE_COLLISION))) -- stats->collisions += -+ x->tx_collision += - (tdes3 & TDES3_COLLISION_COUNT_MASK) - >> TDES3_COLLISION_COUNT_SHIFT; - -@@ -73,8 +70,7 @@ static int dwmac4_wrback_get_tx_status(struct net_device_stats *stats, - return ret; - } - --static int dwmac4_wrback_get_rx_status(struct net_device_stats *stats, -- struct stmmac_extra_stats *x, -+static int dwmac4_wrback_get_rx_status(struct stmmac_extra_stats *x, - struct dma_desc *p) - { - unsigned int rdes1 = le32_to_cpu(p->des1); -@@ -93,7 +89,7 @@ static int dwmac4_wrback_get_rx_status(struct net_device_stats *stats, - - if (unlikely(rdes3 & RDES3_ERROR_SUMMARY)) { - if (unlikely(rdes3 & RDES3_GIANT_PACKET)) -- stats->rx_length_errors++; -+ x->rx_length++; - if (unlikely(rdes3 & RDES3_OVERFLOW_ERROR)) - x->rx_gmac_overflow++; - -@@ -103,10 +99,8 @@ static int dwmac4_wrback_get_rx_status(struct net_device_stats *stats, - if (unlikely(rdes3 & RDES3_RECEIVE_ERROR)) - x->rx_mii++; - -- if (unlikely(rdes3 & RDES3_CRC_ERROR)) { -+ if (unlikely(rdes3 & RDES3_CRC_ERROR)) - x->rx_crc_errors++; -- stats->rx_crc_errors++; -- } - - if (unlikely(rdes3 & RDES3_DRIBBLE_ERROR)) - x->dribbling_bit++; -diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c -index 03ceb6a940732..980e5f8a37ec5 100644 ---- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c -+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c -@@ -171,6 +171,8 @@ int dwmac4_dma_interrupt(struct stmmac_priv *priv, void __iomem *ioaddr, - const struct dwmac4_addrs *dwmac4_addrs = priv->plat->dwmac4_addrs; - u32 intr_status = readl(ioaddr + DMA_CHAN_STATUS(dwmac4_addrs, chan)); - u32 intr_en = readl(ioaddr + DMA_CHAN_INTR_ENA(dwmac4_addrs, chan)); -+ struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[chan]; -+ struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[chan]; - int ret = 0; - - if (dir == DMA_DIR_RX) -@@ -198,18 +200,19 @@ int dwmac4_dma_interrupt(struct stmmac_priv *priv, void __iomem *ioaddr, - } - } - /* TX/RX NORMAL interrupts */ -- if (likely(intr_status & DMA_CHAN_STATUS_NIS)) -- x->normal_irq_n++; - if (likely(intr_status & DMA_CHAN_STATUS_RI)) { -- x->rx_normal_irq_n++; -- x->rxq_stats[chan].rx_normal_irq_n++; -+ u64_stats_update_begin(&rx_q->rxq_stats.syncp); -+ rx_q->rxq_stats.rx_normal_irq_n++; -+ u64_stats_update_end(&rx_q->rxq_stats.syncp); - ret |= handle_rx; - } - if (likely(intr_status & DMA_CHAN_STATUS_TI)) { -- x->tx_normal_irq_n++; -- x->txq_stats[chan].tx_normal_irq_n++; -+ u64_stats_update_begin(&tx_q->txq_stats.syncp); -+ tx_q->txq_stats.tx_normal_irq_n++; -+ u64_stats_update_end(&tx_q->txq_stats.syncp); - ret |= handle_tx; - } -+ - if (unlikely(intr_status & DMA_CHAN_STATUS_TBU)) - ret |= handle_tx; - if (unlikely(intr_status & DMA_CHAN_STATUS_ERI)) -diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c b/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c -index 0b6f999a83052..aaa09b16b016f 100644 ---- a/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c -+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c -@@ -10,6 +10,7 @@ - #include - #include "common.h" - #include "dwmac_dma.h" -+#include "stmmac.h" - - #define GMAC_HI_REG_AE 0x80000000 - -@@ -161,6 +162,8 @@ static void show_rx_process_state(unsigned int status) - int dwmac_dma_interrupt(struct stmmac_priv *priv, void __iomem *ioaddr, - struct stmmac_extra_stats *x, u32 chan, u32 dir) - { -+ struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[chan]; -+ struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[chan]; - int ret = 0; - /* read the status register (CSR5) */ - u32 intr_status = readl(ioaddr + DMA_STATUS); -@@ -208,17 +211,20 @@ int dwmac_dma_interrupt(struct stmmac_priv *priv, void __iomem *ioaddr, - } - /* TX/RX NORMAL interrupts */ - if (likely(intr_status & DMA_STATUS_NIS)) { -- x->normal_irq_n++; - if (likely(intr_status & DMA_STATUS_RI)) { - u32 value = readl(ioaddr + DMA_INTR_ENA); - /* to schedule NAPI on real RIE event. */ - if (likely(value & DMA_INTR_ENA_RIE)) { -- x->rx_normal_irq_n++; -+ u64_stats_update_begin(&rx_q->rxq_stats.syncp); -+ rx_q->rxq_stats.rx_normal_irq_n++; -+ u64_stats_update_end(&rx_q->rxq_stats.syncp); - ret |= handle_rx; - } - } - if (likely(intr_status & DMA_STATUS_TI)) { -- x->tx_normal_irq_n++; -+ u64_stats_update_begin(&tx_q->txq_stats.syncp); -+ tx_q->txq_stats.tx_normal_irq_n++; -+ u64_stats_update_end(&tx_q->txq_stats.syncp); - ret |= handle_tx; - } - if (unlikely(intr_status & DMA_STATUS_ERI)) -diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c -index 13c347ee8be9c..fc82862a612c7 100644 ---- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c -+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c -@@ -8,8 +8,7 @@ - #include "common.h" - #include "dwxgmac2.h" - --static int dwxgmac2_get_tx_status(struct net_device_stats *stats, -- struct stmmac_extra_stats *x, -+static int dwxgmac2_get_tx_status(struct stmmac_extra_stats *x, - struct dma_desc *p, void __iomem *ioaddr) - { - unsigned int tdes3 = le32_to_cpu(p->des3); -@@ -23,8 +22,7 @@ static int dwxgmac2_get_tx_status(struct net_device_stats *stats, - return ret; - } - --static int dwxgmac2_get_rx_status(struct net_device_stats *stats, -- struct stmmac_extra_stats *x, -+static int dwxgmac2_get_rx_status(struct stmmac_extra_stats *x, - struct dma_desc *p) - { - unsigned int rdes3 = le32_to_cpu(p->des3); -diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c -index 070bd912580b7..3b5f8c595219b 100644 ---- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c -+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c -@@ -337,6 +337,8 @@ static int dwxgmac2_dma_interrupt(struct stmmac_priv *priv, - struct stmmac_extra_stats *x, u32 chan, - u32 dir) - { -+ struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[chan]; -+ struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[chan]; - u32 intr_status = readl(ioaddr + XGMAC_DMA_CH_STATUS(chan)); - u32 intr_en = readl(ioaddr + XGMAC_DMA_CH_INT_EN(chan)); - int ret = 0; -@@ -364,16 +366,16 @@ static int dwxgmac2_dma_interrupt(struct stmmac_priv *priv, - - /* TX/RX NORMAL interrupts */ - if (likely(intr_status & XGMAC_NIS)) { -- x->normal_irq_n++; -- - if (likely(intr_status & XGMAC_RI)) { -- x->rx_normal_irq_n++; -- x->rxq_stats[chan].rx_normal_irq_n++; -+ u64_stats_update_begin(&rx_q->rxq_stats.syncp); -+ rx_q->rxq_stats.rx_normal_irq_n++; -+ u64_stats_update_end(&rx_q->rxq_stats.syncp); - ret |= handle_rx; - } - if (likely(intr_status & (XGMAC_TI | XGMAC_TBU))) { -- x->tx_normal_irq_n++; -- x->txq_stats[chan].tx_normal_irq_n++; -+ u64_stats_update_begin(&tx_q->txq_stats.syncp); -+ tx_q->txq_stats.tx_normal_irq_n++; -+ u64_stats_update_end(&tx_q->txq_stats.syncp); - ret |= handle_tx; - } - } -diff --git a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c -index a91d8f13a931d..937b7a0466fca 100644 ---- a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c -+++ b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c -@@ -12,8 +12,7 @@ - #include "common.h" - #include "descs_com.h" - --static int enh_desc_get_tx_status(struct net_device_stats *stats, -- struct stmmac_extra_stats *x, -+static int enh_desc_get_tx_status(struct stmmac_extra_stats *x, - struct dma_desc *p, void __iomem *ioaddr) - { - unsigned int tdes0 = le32_to_cpu(p->des0); -@@ -38,15 +37,13 @@ static int enh_desc_get_tx_status(struct net_device_stats *stats, - - if (unlikely(tdes0 & ETDES0_LOSS_CARRIER)) { - x->tx_losscarrier++; -- stats->tx_carrier_errors++; - } - if (unlikely(tdes0 & ETDES0_NO_CARRIER)) { - x->tx_carrier++; -- stats->tx_carrier_errors++; - } - if (unlikely((tdes0 & ETDES0_LATE_COLLISION) || - (tdes0 & ETDES0_EXCESSIVE_COLLISIONS))) -- stats->collisions += -+ x->tx_collision += - (tdes0 & ETDES0_COLLISION_COUNT_MASK) >> 3; - - if (unlikely(tdes0 & ETDES0_EXCESSIVE_DEFERRAL)) -@@ -117,8 +114,7 @@ static int enh_desc_coe_rdes0(int ipc_err, int type, int payload_err) - return ret; - } - --static void enh_desc_get_ext_status(struct net_device_stats *stats, -- struct stmmac_extra_stats *x, -+static void enh_desc_get_ext_status(struct stmmac_extra_stats *x, - struct dma_extended_desc *p) - { - unsigned int rdes0 = le32_to_cpu(p->basic.des0); -@@ -182,8 +178,7 @@ static void enh_desc_get_ext_status(struct net_device_stats *stats, - } - } - --static int enh_desc_get_rx_status(struct net_device_stats *stats, -- struct stmmac_extra_stats *x, -+static int enh_desc_get_rx_status(struct stmmac_extra_stats *x, - struct dma_desc *p) - { - unsigned int rdes0 = le32_to_cpu(p->des0); -@@ -193,14 +188,14 @@ static int enh_desc_get_rx_status(struct net_device_stats *stats, - return dma_own; - - if (unlikely(!(rdes0 & RDES0_LAST_DESCRIPTOR))) { -- stats->rx_length_errors++; -+ x->rx_length++; - return discard_frame; - } - - if (unlikely(rdes0 & RDES0_ERROR_SUMMARY)) { - if (unlikely(rdes0 & RDES0_DESCRIPTOR_ERROR)) { - x->rx_desc++; -- stats->rx_length_errors++; -+ x->rx_length++; - } - if (unlikely(rdes0 & RDES0_OVERFLOW_ERROR)) - x->rx_gmac_overflow++; -@@ -209,7 +204,7 @@ static int enh_desc_get_rx_status(struct net_device_stats *stats, - pr_err("\tIPC Csum Error/Giant frame\n"); - - if (unlikely(rdes0 & RDES0_COLLISION)) -- stats->collisions++; -+ x->rx_collision++; - if (unlikely(rdes0 & RDES0_RECEIVE_WATCHDOG)) - x->rx_watchdog++; - -@@ -218,7 +213,6 @@ static int enh_desc_get_rx_status(struct net_device_stats *stats, - - if (unlikely(rdes0 & RDES0_CRC_ERROR)) { - x->rx_crc_errors++; -- stats->rx_crc_errors++; - } - ret = discard_frame; - } -diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.h b/drivers/net/ethernet/stmicro/stmmac/hwif.h -index 6ee7cf07cfd76..652af8f6e75ff 100644 ---- a/drivers/net/ethernet/stmicro/stmmac/hwif.h -+++ b/drivers/net/ethernet/stmicro/stmmac/hwif.h -@@ -57,8 +57,7 @@ struct stmmac_desc_ops { - /* Last tx segment reports the transmit status */ - int (*get_tx_ls)(struct dma_desc *p); - /* Return the transmit status looking at the TDES1 */ -- int (*tx_status)(struct net_device_stats *stats, -- struct stmmac_extra_stats *x, -+ int (*tx_status)(struct stmmac_extra_stats *x, - struct dma_desc *p, void __iomem *ioaddr); - /* Get the buffer size from the descriptor */ - int (*get_tx_len)(struct dma_desc *p); -@@ -67,11 +66,9 @@ struct stmmac_desc_ops { - /* Get the receive frame size */ - int (*get_rx_frame_len)(struct dma_desc *p, int rx_coe_type); - /* Return the reception status looking at the RDES1 */ -- int (*rx_status)(struct net_device_stats *stats, -- struct stmmac_extra_stats *x, -+ int (*rx_status)(struct stmmac_extra_stats *x, - struct dma_desc *p); -- void (*rx_extended_status)(struct net_device_stats *stats, -- struct stmmac_extra_stats *x, -+ void (*rx_extended_status)(struct stmmac_extra_stats *x, - struct dma_extended_desc *p); - /* Set tx timestamp enable bit */ - void (*enable_tx_timestamp) (struct dma_desc *p); -@@ -191,8 +188,7 @@ struct stmmac_dma_ops { - void (*dma_tx_mode)(struct stmmac_priv *priv, void __iomem *ioaddr, - int mode, u32 channel, int fifosz, u8 qmode); - /* To track extra statistic (if supported) */ -- void (*dma_diagnostic_fr)(struct net_device_stats *stats, -- struct stmmac_extra_stats *x, -+ void (*dma_diagnostic_fr)(struct stmmac_extra_stats *x, - void __iomem *ioaddr); - void (*enable_dma_transmission) (void __iomem *ioaddr); - void (*enable_dma_irq)(struct stmmac_priv *priv, void __iomem *ioaddr, -diff --git a/drivers/net/ethernet/stmicro/stmmac/norm_desc.c b/drivers/net/ethernet/stmicro/stmmac/norm_desc.c -index 350e6670a5766..68a7cfcb1d8f3 100644 ---- a/drivers/net/ethernet/stmicro/stmmac/norm_desc.c -+++ b/drivers/net/ethernet/stmicro/stmmac/norm_desc.c -@@ -12,8 +12,7 @@ - #include "common.h" - #include "descs_com.h" - --static int ndesc_get_tx_status(struct net_device_stats *stats, -- struct stmmac_extra_stats *x, -+static int ndesc_get_tx_status(struct stmmac_extra_stats *x, - struct dma_desc *p, void __iomem *ioaddr) - { - unsigned int tdes0 = le32_to_cpu(p->des0); -@@ -31,15 +30,12 @@ static int ndesc_get_tx_status(struct net_device_stats *stats, - if (unlikely(tdes0 & TDES0_ERROR_SUMMARY)) { - if (unlikely(tdes0 & TDES0_UNDERFLOW_ERROR)) { - x->tx_underflow++; -- stats->tx_fifo_errors++; - } - if (unlikely(tdes0 & TDES0_NO_CARRIER)) { - x->tx_carrier++; -- stats->tx_carrier_errors++; - } - if (unlikely(tdes0 & TDES0_LOSS_CARRIER)) { - x->tx_losscarrier++; -- stats->tx_carrier_errors++; - } - if (unlikely((tdes0 & TDES0_EXCESSIVE_DEFERRAL) || - (tdes0 & TDES0_EXCESSIVE_COLLISIONS) || -@@ -47,7 +43,7 @@ static int ndesc_get_tx_status(struct net_device_stats *stats, - unsigned int collisions; - - collisions = (tdes0 & TDES0_COLLISION_COUNT_MASK) >> 3; -- stats->collisions += collisions; -+ x->tx_collision += collisions; - } - ret = tx_err; - } -@@ -70,8 +66,7 @@ static int ndesc_get_tx_len(struct dma_desc *p) - * and, if required, updates the multicast statistics. - * In case of success, it returns good_frame because the GMAC device - * is supposed to be able to compute the csum in HW. */ --static int ndesc_get_rx_status(struct net_device_stats *stats, -- struct stmmac_extra_stats *x, -+static int ndesc_get_rx_status(struct stmmac_extra_stats *x, - struct dma_desc *p) - { - int ret = good_frame; -@@ -81,7 +76,7 @@ static int ndesc_get_rx_status(struct net_device_stats *stats, - return dma_own; - - if (unlikely(!(rdes0 & RDES0_LAST_DESCRIPTOR))) { -- stats->rx_length_errors++; -+ x->rx_length++; - return discard_frame; - } - -@@ -96,11 +91,9 @@ static int ndesc_get_rx_status(struct net_device_stats *stats, - x->ipc_csum_error++; - if (unlikely(rdes0 & RDES0_COLLISION)) { - x->rx_collision++; -- stats->collisions++; - } - if (unlikely(rdes0 & RDES0_CRC_ERROR)) { - x->rx_crc_errors++; -- stats->rx_crc_errors++; - } - ret = discard_frame; - } -diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h -index 07ea5ab0a60ba..4ce5eaaae5135 100644 ---- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h -+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h -@@ -77,6 +77,7 @@ struct stmmac_tx_queue { - dma_addr_t dma_tx_phy; - dma_addr_t tx_tail_addr; - u32 mss; -+ struct stmmac_txq_stats txq_stats; - }; - - struct stmmac_rx_buffer { -@@ -121,6 +122,7 @@ struct stmmac_rx_queue { - unsigned int len; - unsigned int error; - } state; -+ struct stmmac_rxq_stats rxq_stats; - }; - - struct stmmac_channel { -diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c -index 2ae73ab842d45..b7ac7abecdd35 100644 ---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c -+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c -@@ -89,14 +89,6 @@ static const struct stmmac_stats stmmac_gstrings_stats[] = { - /* Tx/Rx IRQ Events */ - STMMAC_STAT(rx_early_irq), - STMMAC_STAT(threshold), -- STMMAC_STAT(tx_pkt_n), -- STMMAC_STAT(rx_pkt_n), -- STMMAC_STAT(normal_irq_n), -- STMMAC_STAT(rx_normal_irq_n), -- STMMAC_STAT(napi_poll), -- STMMAC_STAT(tx_normal_irq_n), -- STMMAC_STAT(tx_clean), -- STMMAC_STAT(tx_set_ic_bit), - STMMAC_STAT(irq_receive_pmt_irq_n), - /* MMC info */ - STMMAC_STAT(mmc_tx_irq_n), -@@ -163,9 +155,6 @@ static const struct stmmac_stats stmmac_gstrings_stats[] = { - STMMAC_STAT(mtl_rx_fifo_ctrl_active), - STMMAC_STAT(mac_rx_frame_ctrl_fifo), - STMMAC_STAT(mac_gmii_rx_proto_engine), -- /* TSO */ -- STMMAC_STAT(tx_tso_frames), -- STMMAC_STAT(tx_tso_nfrags), - /* EST */ - STMMAC_STAT(mtl_est_cgce), - STMMAC_STAT(mtl_est_hlbs), -@@ -175,6 +164,23 @@ static const struct stmmac_stats stmmac_gstrings_stats[] = { - }; - #define STMMAC_STATS_LEN ARRAY_SIZE(stmmac_gstrings_stats) - -+/* statistics collected in queue which will be summed up for all TX or RX -+ * queues, or summed up for both TX and RX queues(napi_poll, normal_irq_n). -+ */ -+static const char stmmac_qstats_string[][ETH_GSTRING_LEN] = { -+ "rx_pkt_n", -+ "rx_normal_irq_n", -+ "tx_pkt_n", -+ "tx_normal_irq_n", -+ "tx_clean", -+ "tx_set_ic_bit", -+ "tx_tso_frames", -+ "tx_tso_nfrags", -+ "normal_irq_n", -+ "napi_poll", -+}; -+#define STMMAC_QSTATS ARRAY_SIZE(stmmac_qstats_string) -+ - /* HW MAC Management counters (if supported) */ - #define STMMAC_MMC_STAT(m) \ - { #m, sizeof_field(struct stmmac_counters, m), \ -@@ -535,23 +541,44 @@ static void stmmac_get_per_qstats(struct stmmac_priv *priv, u64 *data) - { - u32 tx_cnt = priv->plat->tx_queues_to_use; - u32 rx_cnt = priv->plat->rx_queues_to_use; -+ unsigned int start; - int q, stat; -+ u64 *pos; - char *p; - -+ pos = data; - for (q = 0; q < tx_cnt; q++) { -- p = (char *)priv + offsetof(struct stmmac_priv, -- xstats.txq_stats[q].tx_pkt_n); -+ struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[q]; -+ struct stmmac_txq_stats snapshot; -+ -+ data = pos; -+ do { -+ start = u64_stats_fetch_begin(&tx_q->txq_stats.syncp); -+ snapshot = tx_q->txq_stats; -+ } while (u64_stats_fetch_retry(&tx_q->txq_stats.syncp, start)); -+ -+ p = (char *)&snapshot + offsetof(struct stmmac_txq_stats, tx_pkt_n); - for (stat = 0; stat < STMMAC_TXQ_STATS; stat++) { -- *data++ = (*(unsigned long *)p); -- p += sizeof(unsigned long); -+ *data++ += (*(u64 *)p); -+ p += sizeof(u64); - } - } -+ -+ pos = data; - for (q = 0; q < rx_cnt; q++) { -- p = (char *)priv + offsetof(struct stmmac_priv, -- xstats.rxq_stats[q].rx_pkt_n); -+ struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[q]; -+ struct stmmac_rxq_stats snapshot; -+ -+ data = pos; -+ do { -+ start = u64_stats_fetch_begin(&rx_q->rxq_stats.syncp); -+ snapshot = rx_q->rxq_stats; -+ } while (u64_stats_fetch_retry(&rx_q->rxq_stats.syncp, start)); -+ -+ p = (char *)&snapshot + offsetof(struct stmmac_rxq_stats, rx_pkt_n); - for (stat = 0; stat < STMMAC_RXQ_STATS; stat++) { -- *data++ = (*(unsigned long *)p); -- p += sizeof(unsigned long); -+ *data++ += (*(u64 *)p); -+ p += sizeof(u64); - } - } - } -@@ -562,8 +589,10 @@ static void stmmac_get_ethtool_stats(struct net_device *dev, - struct stmmac_priv *priv = netdev_priv(dev); - u32 rx_queues_count = priv->plat->rx_queues_to_use; - u32 tx_queues_count = priv->plat->tx_queues_to_use; -+ u64 napi_poll = 0, normal_irq_n = 0; -+ int i, j = 0, pos, ret; - unsigned long count; -- int i, j = 0, ret; -+ unsigned int start; - - if (priv->dma_cap.asp) { - for (i = 0; i < STMMAC_SAFETY_FEAT_SIZE; i++) { -@@ -574,8 +603,7 @@ static void stmmac_get_ethtool_stats(struct net_device *dev, - } - - /* Update the DMA HW counters for dwmac10/100 */ -- ret = stmmac_dma_diagnostic_fr(priv, &dev->stats, (void *) &priv->xstats, -- priv->ioaddr); -+ ret = stmmac_dma_diagnostic_fr(priv, &priv->xstats, priv->ioaddr); - if (ret) { - /* If supported, for new GMAC chips expose the MMC counters */ - if (priv->dma_cap.rmon) { -@@ -606,6 +634,48 @@ static void stmmac_get_ethtool_stats(struct net_device *dev, - data[j++] = (stmmac_gstrings_stats[i].sizeof_stat == - sizeof(u64)) ? (*(u64 *)p) : (*(u32 *)p); - } -+ -+ pos = j; -+ for (i = 0; i < rx_queues_count; i++) { -+ struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[i]; -+ struct stmmac_rxq_stats snapshot; -+ -+ j = pos; -+ do { -+ start = u64_stats_fetch_begin(&rx_q->rxq_stats.syncp); -+ snapshot = rx_q->rxq_stats; -+ } while (u64_stats_fetch_retry(&rx_q->rxq_stats.syncp, start)); -+ -+ data[j++] += snapshot.rx_pkt_n; -+ data[j++] += snapshot.rx_normal_irq_n; -+ normal_irq_n += snapshot.rx_normal_irq_n; -+ napi_poll += snapshot.napi_poll; -+ } -+ -+ pos = j; -+ for (i = 0; i < tx_queues_count; i++) { -+ struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[i]; -+ struct stmmac_txq_stats snapshot; -+ -+ j = pos; -+ do { -+ start = u64_stats_fetch_begin(&tx_q->txq_stats.syncp); -+ snapshot = tx_q->txq_stats; -+ } while (u64_stats_fetch_retry(&tx_q->txq_stats.syncp, start)); -+ -+ data[j++] += snapshot.tx_pkt_n; -+ data[j++] += snapshot.tx_normal_irq_n; -+ normal_irq_n += snapshot.tx_normal_irq_n; -+ data[j++] += snapshot.tx_clean; -+ data[j++] += snapshot.tx_set_ic_bit; -+ data[j++] += snapshot.tx_tso_frames; -+ data[j++] += snapshot.tx_tso_nfrags; -+ napi_poll += snapshot.napi_poll; -+ } -+ normal_irq_n += priv->xstats.rx_early_irq; -+ data[j++] = normal_irq_n; -+ data[j++] = napi_poll; -+ - stmmac_get_per_qstats(priv, &data[j]); - } - -@@ -618,7 +688,7 @@ static int stmmac_get_sset_count(struct net_device *netdev, int sset) - - switch (sset) { - case ETH_SS_STATS: -- len = STMMAC_STATS_LEN + -+ len = STMMAC_STATS_LEN + STMMAC_QSTATS + - STMMAC_TXQ_STATS * tx_cnt + - STMMAC_RXQ_STATS * rx_cnt; - -@@ -691,8 +761,11 @@ static void stmmac_get_strings(struct net_device *dev, u32 stringset, u8 *data) - p += ETH_GSTRING_LEN; - } - for (i = 0; i < STMMAC_STATS_LEN; i++) { -- memcpy(p, stmmac_gstrings_stats[i].stat_string, -- ETH_GSTRING_LEN); -+ memcpy(p, stmmac_gstrings_stats[i].stat_string, ETH_GSTRING_LEN); -+ p += ETH_GSTRING_LEN; -+ } -+ for (i = 0; i < STMMAC_QSTATS; i++) { -+ memcpy(p, stmmac_qstats_string[i], ETH_GSTRING_LEN); - p += ETH_GSTRING_LEN; - } - stmmac_get_qstats_string(priv, p); -diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -index 6931973028aef..def490a1e2120 100644 ---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -@@ -2432,6 +2432,8 @@ static bool stmmac_xdp_xmit_zc(struct stmmac_priv *priv, u32 queue, u32 budget) - struct dma_desc *tx_desc = NULL; - struct xdp_desc xdp_desc; - bool work_done = true; -+ u32 tx_set_ic_bit = 0; -+ unsigned long flags; - - /* Avoids TX time-out as we are sharing with slow path */ - txq_trans_cond_update(nq); -@@ -2492,7 +2494,7 @@ static bool stmmac_xdp_xmit_zc(struct stmmac_priv *priv, u32 queue, u32 budget) - if (set_ic) { - tx_q->tx_count_frames = 0; - stmmac_set_tx_ic(priv, tx_desc); -- priv->xstats.tx_set_ic_bit++; -+ tx_set_ic_bit++; - } - - stmmac_prepare_tx_desc(priv, tx_desc, 1, xdp_desc.len, -@@ -2504,6 +2506,9 @@ static bool stmmac_xdp_xmit_zc(struct stmmac_priv *priv, u32 queue, u32 budget) - tx_q->cur_tx = STMMAC_GET_ENTRY(tx_q->cur_tx, priv->dma_conf.dma_tx_size); - entry = tx_q->cur_tx; - } -+ flags = u64_stats_update_begin_irqsave(&tx_q->txq_stats.syncp); -+ tx_q->txq_stats.tx_set_ic_bit += tx_set_ic_bit; -+ u64_stats_update_end_irqrestore(&tx_q->txq_stats.syncp, flags); - - if (tx_desc) { - stmmac_flush_tx_descriptors(priv, queue); -@@ -2545,11 +2550,11 @@ static int stmmac_tx_clean(struct stmmac_priv *priv, int budget, u32 queue) - struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue]; - unsigned int bytes_compl = 0, pkts_compl = 0; - unsigned int entry, xmits = 0, count = 0; -+ u32 tx_packets = 0, tx_errors = 0; -+ unsigned long flags; - - __netif_tx_lock_bh(netdev_get_tx_queue(priv->dev, queue)); - -- priv->xstats.tx_clean++; -- - tx_q->xsk_frames_done = 0; - - entry = tx_q->dirty_tx; -@@ -2580,8 +2585,7 @@ static int stmmac_tx_clean(struct stmmac_priv *priv, int budget, u32 queue) - else - p = tx_q->dma_tx + entry; - -- status = stmmac_tx_status(priv, &priv->dev->stats, -- &priv->xstats, p, priv->ioaddr); -+ status = stmmac_tx_status(priv, &priv->xstats, p, priv->ioaddr); - /* Check if the descriptor is owned by the DMA */ - if (unlikely(status & tx_dma_own)) - break; -@@ -2597,13 +2601,11 @@ static int stmmac_tx_clean(struct stmmac_priv *priv, int budget, u32 queue) - if (likely(!(status & tx_not_ls))) { - /* ... verify the status error condition */ - if (unlikely(status & tx_err)) { -- priv->dev->stats.tx_errors++; -+ tx_errors++; - if (unlikely(status & tx_err_bump_tc)) - stmmac_bump_dma_threshold(priv, queue); - } else { -- priv->dev->stats.tx_packets++; -- priv->xstats.tx_pkt_n++; -- priv->xstats.txq_stats[queue].tx_pkt_n++; -+ tx_packets++; - } - if (skb) - stmmac_get_tx_hwtstamp(priv, p, skb); -@@ -2705,6 +2707,14 @@ static int stmmac_tx_clean(struct stmmac_priv *priv, int budget, u32 queue) - if (tx_q->dirty_tx != tx_q->cur_tx) - stmmac_tx_timer_arm(priv, queue); - -+ flags = u64_stats_update_begin_irqsave(&tx_q->txq_stats.syncp); -+ tx_q->txq_stats.tx_packets += tx_packets; -+ tx_q->txq_stats.tx_pkt_n += tx_packets; -+ tx_q->txq_stats.tx_clean++; -+ u64_stats_update_end_irqrestore(&tx_q->txq_stats.syncp, flags); -+ -+ priv->xstats.tx_errors += tx_errors; -+ - __netif_tx_unlock_bh(netdev_get_tx_queue(priv->dev, queue)); - - /* Combine decisions from TX clean and XSK TX */ -@@ -2732,7 +2742,7 @@ static void stmmac_tx_err(struct stmmac_priv *priv, u32 chan) - tx_q->dma_tx_phy, chan); - stmmac_start_tx_dma(priv, chan); - -- priv->dev->stats.tx_errors++; -+ priv->xstats.tx_errors++; - netif_tx_wake_queue(netdev_get_tx_queue(priv->dev, chan)); - } - -@@ -4112,6 +4122,7 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev) - struct stmmac_tx_queue *tx_q; - bool has_vlan, set_ic; - u8 proto_hdr_len, hdr; -+ unsigned long flags; - u32 pay_len, mss; - dma_addr_t des; - int i; -@@ -4260,7 +4271,6 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev) - - tx_q->tx_count_frames = 0; - stmmac_set_tx_ic(priv, desc); -- priv->xstats.tx_set_ic_bit++; - } - - /* We've used all descriptors we need for this skb, however, -@@ -4276,9 +4286,13 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev) - netif_tx_stop_queue(netdev_get_tx_queue(priv->dev, queue)); - } - -- dev->stats.tx_bytes += skb->len; -- priv->xstats.tx_tso_frames++; -- priv->xstats.tx_tso_nfrags += nfrags; -+ flags = u64_stats_update_begin_irqsave(&tx_q->txq_stats.syncp); -+ tx_q->txq_stats.tx_bytes += skb->len; -+ tx_q->txq_stats.tx_tso_frames++; -+ tx_q->txq_stats.tx_tso_nfrags += nfrags; -+ if (set_ic) -+ tx_q->txq_stats.tx_set_ic_bit++; -+ u64_stats_update_end_irqrestore(&tx_q->txq_stats.syncp, flags); - - if (priv->sarc_type) - stmmac_set_desc_sarc(priv, first, priv->sarc_type); -@@ -4328,7 +4342,7 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev) - dma_map_err: - dev_err(priv->device, "Tx dma map failed\n"); - dev_kfree_skb(skb); -- priv->dev->stats.tx_dropped++; -+ priv->xstats.tx_dropped++; - return NETDEV_TX_OK; - } - -@@ -4354,6 +4368,7 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) - struct stmmac_tx_queue *tx_q; - bool has_vlan, set_ic; - int entry, first_tx; -+ unsigned long flags; - dma_addr_t des; - - tx_q = &priv->dma_conf.tx_queue[queue]; -@@ -4482,7 +4497,6 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) - - tx_q->tx_count_frames = 0; - stmmac_set_tx_ic(priv, desc); -- priv->xstats.tx_set_ic_bit++; - } - - /* We've used all descriptors we need for this skb, however, -@@ -4509,7 +4523,11 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) - netif_tx_stop_queue(netdev_get_tx_queue(priv->dev, queue)); - } - -- dev->stats.tx_bytes += skb->len; -+ flags = u64_stats_update_begin_irqsave(&tx_q->txq_stats.syncp); -+ tx_q->txq_stats.tx_bytes += skb->len; -+ if (set_ic) -+ tx_q->txq_stats.tx_set_ic_bit++; -+ u64_stats_update_end_irqrestore(&tx_q->txq_stats.syncp, flags); - - if (priv->sarc_type) - stmmac_set_desc_sarc(priv, first, priv->sarc_type); -@@ -4571,7 +4589,7 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) - dma_map_err: - netdev_err(priv->dev, "Tx DMA map failed\n"); - dev_kfree_skb(skb); -- priv->dev->stats.tx_dropped++; -+ priv->xstats.tx_dropped++; - return NETDEV_TX_OK; - } - -@@ -4772,9 +4790,12 @@ static int stmmac_xdp_xmit_xdpf(struct stmmac_priv *priv, int queue, - set_ic = false; - - if (set_ic) { -+ unsigned long flags; - tx_q->tx_count_frames = 0; - stmmac_set_tx_ic(priv, tx_desc); -- priv->xstats.tx_set_ic_bit++; -+ flags = u64_stats_update_begin_irqsave(&tx_q->txq_stats.syncp); -+ tx_q->txq_stats.tx_set_ic_bit++; -+ u64_stats_update_end_irqrestore(&tx_q->txq_stats.syncp, flags); - } - - stmmac_enable_dma_transmission(priv, priv->ioaddr); -@@ -4919,16 +4940,18 @@ static void stmmac_dispatch_skb_zc(struct stmmac_priv *priv, u32 queue, - struct dma_desc *p, struct dma_desc *np, - struct xdp_buff *xdp) - { -+ struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue]; - struct stmmac_channel *ch = &priv->channel[queue]; - unsigned int len = xdp->data_end - xdp->data; - enum pkt_hash_types hash_type; - int coe = priv->hw->rx_csum; -+ unsigned long flags; - struct sk_buff *skb; - u32 hash; - - skb = stmmac_construct_skb_zc(ch, xdp); - if (!skb) { -- priv->dev->stats.rx_dropped++; -+ priv->xstats.rx_dropped++; - return; - } - -@@ -4947,8 +4970,10 @@ static void stmmac_dispatch_skb_zc(struct stmmac_priv *priv, u32 queue, - skb_record_rx_queue(skb, queue); - napi_gro_receive(&ch->rxtx_napi, skb); - -- priv->dev->stats.rx_packets++; -- priv->dev->stats.rx_bytes += len; -+ flags = u64_stats_update_begin_irqsave(&rx_q->rxq_stats.syncp); -+ rx_q->rxq_stats.rx_pkt_n++; -+ rx_q->rxq_stats.rx_bytes += len; -+ u64_stats_update_end_irqrestore(&rx_q->rxq_stats.syncp, flags); - } - - static bool stmmac_rx_refill_zc(struct stmmac_priv *priv, u32 queue, u32 budget) -@@ -5025,9 +5050,11 @@ static int stmmac_rx_zc(struct stmmac_priv *priv, int limit, u32 queue) - unsigned int count = 0, error = 0, len = 0; - int dirty = stmmac_rx_dirty(priv, queue); - unsigned int next_entry = rx_q->cur_rx; -+ u32 rx_errors = 0, rx_dropped = 0; - unsigned int desc_size; - struct bpf_prog *prog; - bool failure = false; -+ unsigned long flags; - int xdp_status = 0; - int status = 0; - -@@ -5083,8 +5110,7 @@ static int stmmac_rx_zc(struct stmmac_priv *priv, int limit, u32 queue) - p = rx_q->dma_rx + entry; - - /* read the status of the incoming frame */ -- status = stmmac_rx_status(priv, &priv->dev->stats, -- &priv->xstats, p); -+ status = stmmac_rx_status(priv, &priv->xstats, p); - /* check if managed by the DMA otherwise go ahead */ - if (unlikely(status & dma_own)) - break; -@@ -5106,8 +5132,7 @@ static int stmmac_rx_zc(struct stmmac_priv *priv, int limit, u32 queue) - break; - - if (priv->extend_desc) -- stmmac_rx_extended_status(priv, &priv->dev->stats, -- &priv->xstats, -+ stmmac_rx_extended_status(priv, &priv->xstats, - rx_q->dma_erx + entry); - if (unlikely(status == discard_frame)) { - xsk_buff_free(buf->xdp); -@@ -5115,7 +5140,7 @@ static int stmmac_rx_zc(struct stmmac_priv *priv, int limit, u32 queue) - dirty++; - error = 1; - if (!priv->hwts_rx_en) -- priv->dev->stats.rx_errors++; -+ rx_errors++; - } - - if (unlikely(error && (status & rx_not_ls))) -@@ -5163,7 +5188,7 @@ static int stmmac_rx_zc(struct stmmac_priv *priv, int limit, u32 queue) - break; - case STMMAC_XDP_CONSUMED: - xsk_buff_free(buf->xdp); -- priv->dev->stats.rx_dropped++; -+ rx_dropped++; - break; - case STMMAC_XDP_TX: - case STMMAC_XDP_REDIRECT: -@@ -5184,8 +5209,12 @@ static int stmmac_rx_zc(struct stmmac_priv *priv, int limit, u32 queue) - - stmmac_finalize_xdp_rx(priv, xdp_status); - -- priv->xstats.rx_pkt_n += count; -- priv->xstats.rxq_stats[queue].rx_pkt_n += count; -+ flags = u64_stats_update_begin_irqsave(&rx_q->rxq_stats.syncp); -+ rx_q->rxq_stats.rx_pkt_n += count; -+ u64_stats_update_end_irqrestore(&rx_q->rxq_stats.syncp, flags); -+ -+ priv->xstats.rx_dropped += rx_dropped; -+ priv->xstats.rx_errors += rx_errors; - - if (xsk_uses_need_wakeup(rx_q->xsk_pool)) { - if (failure || stmmac_rx_dirty(priv, queue) > 0) -@@ -5209,6 +5238,7 @@ static int stmmac_rx_zc(struct stmmac_priv *priv, int limit, u32 queue) - */ - static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue) - { -+ u32 rx_errors = 0, rx_dropped = 0, rx_bytes = 0, rx_packets = 0; - struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue]; - struct stmmac_channel *ch = &priv->channel[queue]; - unsigned int count = 0, error = 0, len = 0; -@@ -5218,6 +5248,7 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue) - unsigned int desc_size; - struct sk_buff *skb = NULL; - struct stmmac_xdp_buff ctx; -+ unsigned long flags; - int xdp_status = 0; - int buf_sz; - -@@ -5273,8 +5304,7 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue) - p = rx_q->dma_rx + entry; - - /* read the status of the incoming frame */ -- status = stmmac_rx_status(priv, &priv->dev->stats, -- &priv->xstats, p); -+ status = stmmac_rx_status(priv, &priv->xstats, p); - /* check if managed by the DMA otherwise go ahead */ - if (unlikely(status & dma_own)) - break; -@@ -5291,14 +5321,13 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue) - prefetch(np); - - if (priv->extend_desc) -- stmmac_rx_extended_status(priv, &priv->dev->stats, -- &priv->xstats, rx_q->dma_erx + entry); -+ stmmac_rx_extended_status(priv, &priv->xstats, rx_q->dma_erx + entry); - if (unlikely(status == discard_frame)) { - page_pool_recycle_direct(rx_q->page_pool, buf->page); - buf->page = NULL; - error = 1; - if (!priv->hwts_rx_en) -- priv->dev->stats.rx_errors++; -+ rx_errors++; - } - - if (unlikely(error && (status & rx_not_ls))) -@@ -5366,7 +5395,7 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue) - virt_to_head_page(ctx.xdp.data), - sync_len, true); - buf->page = NULL; -- priv->dev->stats.rx_dropped++; -+ rx_dropped++; - - /* Clear skb as it was set as - * status by XDP program. -@@ -5395,7 +5424,7 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue) - - skb = napi_alloc_skb(&ch->rx_napi, buf1_len); - if (!skb) { -- priv->dev->stats.rx_dropped++; -+ rx_dropped++; - count++; - goto drain_data; - } -@@ -5455,8 +5484,8 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue) - napi_gro_receive(&ch->rx_napi, skb); - skb = NULL; - -- priv->dev->stats.rx_packets++; -- priv->dev->stats.rx_bytes += len; -+ rx_packets++; -+ rx_bytes += len; - count++; - } - -@@ -5471,8 +5500,14 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue) - - stmmac_rx_refill(priv, queue); - -- priv->xstats.rx_pkt_n += count; -- priv->xstats.rxq_stats[queue].rx_pkt_n += count; -+ flags = u64_stats_update_begin_irqsave(&rx_q->rxq_stats.syncp); -+ rx_q->rxq_stats.rx_packets += rx_packets; -+ rx_q->rxq_stats.rx_bytes += rx_bytes; -+ rx_q->rxq_stats.rx_pkt_n += count; -+ u64_stats_update_end_irqrestore(&rx_q->rxq_stats.syncp, flags); -+ -+ priv->xstats.rx_dropped += rx_dropped; -+ priv->xstats.rx_errors += rx_errors; - - return count; - } -@@ -5482,10 +5517,15 @@ static int stmmac_napi_poll_rx(struct napi_struct *napi, int budget) - struct stmmac_channel *ch = - container_of(napi, struct stmmac_channel, rx_napi); - struct stmmac_priv *priv = ch->priv_data; -+ struct stmmac_rx_queue *rx_q; - u32 chan = ch->index; -+ unsigned long flags; - int work_done; - -- priv->xstats.napi_poll++; -+ rx_q = &priv->dma_conf.rx_queue[chan]; -+ flags = u64_stats_update_begin_irqsave(&rx_q->rxq_stats.syncp); -+ rx_q->rxq_stats.napi_poll++; -+ u64_stats_update_end_irqrestore(&rx_q->rxq_stats.syncp, flags); - - work_done = stmmac_rx(priv, budget, chan); - if (work_done < budget && napi_complete_done(napi, work_done)) { -@@ -5504,10 +5544,15 @@ static int stmmac_napi_poll_tx(struct napi_struct *napi, int budget) - struct stmmac_channel *ch = - container_of(napi, struct stmmac_channel, tx_napi); - struct stmmac_priv *priv = ch->priv_data; -+ struct stmmac_tx_queue *tx_q; - u32 chan = ch->index; -+ unsigned long flags; - int work_done; - -- priv->xstats.napi_poll++; -+ tx_q = &priv->dma_conf.tx_queue[chan]; -+ flags = u64_stats_update_begin_irqsave(&tx_q->txq_stats.syncp); -+ tx_q->txq_stats.napi_poll++; -+ u64_stats_update_end_irqrestore(&tx_q->txq_stats.syncp, flags); - - work_done = stmmac_tx_clean(priv, budget, chan); - work_done = min(work_done, budget); -@@ -5529,9 +5574,20 @@ static int stmmac_napi_poll_rxtx(struct napi_struct *napi, int budget) - container_of(napi, struct stmmac_channel, rxtx_napi); - struct stmmac_priv *priv = ch->priv_data; - int rx_done, tx_done, rxtx_done; -+ struct stmmac_rx_queue *rx_q; -+ struct stmmac_tx_queue *tx_q; - u32 chan = ch->index; -+ unsigned long flags; -+ -+ rx_q = &priv->dma_conf.rx_queue[chan]; -+ flags = u64_stats_update_begin_irqsave(&rx_q->rxq_stats.syncp); -+ rx_q->rxq_stats.napi_poll++; -+ u64_stats_update_end_irqrestore(&rx_q->rxq_stats.syncp, flags); - -- priv->xstats.napi_poll++; -+ tx_q = &priv->dma_conf.tx_queue[chan]; -+ flags = u64_stats_update_begin_irqsave(&tx_q->txq_stats.syncp); -+ tx_q->txq_stats.napi_poll++; -+ u64_stats_update_end_irqrestore(&tx_q->txq_stats.syncp, flags); - - tx_done = stmmac_tx_clean(priv, budget, chan); - tx_done = min(tx_done, budget); -@@ -6790,6 +6846,56 @@ int stmmac_xsk_wakeup(struct net_device *dev, u32 queue, u32 flags) - return 0; - } - -+static void stmmac_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) -+{ -+ struct stmmac_priv *priv = netdev_priv(dev); -+ u32 tx_cnt = priv->plat->tx_queues_to_use; -+ u32 rx_cnt = priv->plat->rx_queues_to_use; -+ unsigned int start; -+ int q; -+ -+ for (q = 0; q < tx_cnt; q++) { -+ struct stmmac_txq_stats *txq_stats = &priv->dma_conf.tx_queue[q].txq_stats; -+ u64 tx_packets; -+ u64 tx_bytes; -+ -+ do { -+ start = u64_stats_fetch_begin(&txq_stats->syncp); -+ tx_packets = txq_stats->tx_packets; -+ tx_bytes = txq_stats->tx_bytes; -+ } while (u64_stats_fetch_retry(&txq_stats->syncp, start)); -+ -+ stats->tx_packets += tx_packets; -+ stats->tx_bytes += tx_bytes; -+ } -+ -+ for (q = 0; q < rx_cnt; q++) { -+ struct stmmac_rxq_stats *rxq_stats = &priv->dma_conf.rx_queue[q].rxq_stats; -+ u64 rx_packets; -+ u64 rx_bytes; -+ -+ do { -+ start = u64_stats_fetch_begin(&rxq_stats->syncp); -+ rx_packets = rxq_stats->rx_packets; -+ rx_bytes = rxq_stats->rx_bytes; -+ } while (u64_stats_fetch_retry(&rxq_stats->syncp, start)); -+ -+ stats->rx_packets += rx_packets; -+ stats->rx_bytes += rx_bytes; -+ } -+ -+ stats->rx_dropped = priv->xstats.rx_dropped; -+ stats->rx_errors = priv->xstats.rx_errors; -+ stats->tx_dropped = priv->xstats.tx_dropped; -+ stats->tx_errors = priv->xstats.tx_errors; -+ stats->tx_carrier_errors = priv->xstats.tx_losscarrier + priv->xstats.tx_carrier; -+ stats->collisions = priv->xstats.tx_collision + priv->xstats.rx_collision; -+ stats->rx_length_errors = priv->xstats.rx_length; -+ stats->rx_crc_errors = priv->xstats.rx_crc_errors; -+ stats->rx_over_errors = priv->xstats.rx_overflow_cntr; -+ stats->rx_missed_errors = priv->xstats.rx_missed_cntr; -+} -+ - static const struct net_device_ops stmmac_netdev_ops = { - .ndo_open = stmmac_open, - .ndo_start_xmit = stmmac_xmit, -@@ -6800,6 +6906,7 @@ static const struct net_device_ops stmmac_netdev_ops = { - .ndo_set_rx_mode = stmmac_set_rx_mode, - .ndo_tx_timeout = stmmac_tx_timeout, - .ndo_eth_ioctl = stmmac_ioctl, -+ .ndo_get_stats64 = stmmac_get_stats64, - .ndo_setup_tc = stmmac_setup_tc, - .ndo_select_queue = stmmac_select_queue, - #ifdef CONFIG_NET_POLL_CONTROLLER -@@ -7162,6 +7269,11 @@ int stmmac_dvr_probe(struct device *device, - priv->device = device; - priv->dev = ndev; - -+ for (i = 0; i < MTL_MAX_RX_QUEUES; i++) -+ u64_stats_init(&priv->dma_conf.rx_queue[i].rxq_stats.syncp); -+ for (i = 0; i < MTL_MAX_TX_QUEUES; i++) -+ u64_stats_init(&priv->dma_conf.tx_queue[i].txq_stats.syncp); -+ - stmmac_set_ethtool_ops(ndev); - priv->pause = pause; - priv->plat = plat_dat; --- -2.40.1 - diff --git a/queue-6.5/series b/queue-6.5/series index 90bf1dbb172..f7b56f508de 100644 --- a/queue-6.5/series +++ b/queue-6.5/series @@ -22,7 +22,6 @@ selftests-nolibc-prevent-out-of-bounds-access-in-exp.patch spi-sun6i-add-quirk-for-dual-and-quad-spi-modes-supp.patch devlink-remove-reload-failed-checks-in-params-get-se.patch crypto-lrw-xts-replace-strlcpy-with-strscpy.patch -net-stmmac-use-per-queue-64-bit-statistics-where-nec.patch ice-don-t-tx-before-switchdev-is-fully-configured.patch wifi-ath9k-fix-fortify-warnings.patch wifi-ath9k-fix-printk-specifier.patch @@ -155,7 +154,6 @@ x86-sched-restore-the-sd_asym_packing-flag-in-the-di.patch scsi-target-core-fix-target_cmd_counter-leak.patch scsi-lpfc-fix-the-null-vs-is_err-bug-for-debugfs_cre.patch panic-reenable-preemption-in-warn-slowpath.patch -ata-libata-remove-references-to-non-existing-error_h.patch ata-libata-core-fetch-sense-data-for-successful-comm.patch x86-boot-compressed-reserve-more-memory-for-page-tab.patch x86-purgatory-remove-lto-flags.patch -- 2.47.3