All of lore.kernel.org
 help / color / mirror / Atom feed
From: Niklas Cassel <cassel@kernel.org>
To: Damien Le Moal <dlemoal@kernel.org>
Cc: linux-ide@vger.kernel.org
Subject: Re: [PATCH v5 9/9] ata: libata: Improve CDL resource management
Date: Fri, 6 Sep 2024 10:51:40 +0200	[thread overview]
Message-ID: <ZtrCnMOLAfR5uoUz@ryzen.lan> (raw)
In-Reply-To: <20240906015847.229539-10-dlemoal@kernel.org>

On Fri, Sep 06, 2024 at 10:58:47AM +0900, Damien Le Moal wrote:
> The ncq_sense_buf buffer field of struct ata_port is allocated and used
> only for devices that support the Command Duration Limits (CDL) feature.
> However, the cdl buffer of struct ata_device, which is used to cache the
> command duration limits log page for devices supporting CDL is always
> allocated as part of struct ata_device, which is wasteful of memory for
> devices that do not support this feature.
> 
> Clean this up by defining both buffers as part of the new ata_cdl
> structure and allocating this structure only for devices that support
> the CDL feature. This new structure is attached to struct ata_device
> using the cdl pointer.
> 
> The functions ata_dev_init_cdl_resources() and
> ata_dev_cleanup_cdl_resources() are defined to manage this new structure
> allocation, initialization and freeing when a port is removed or a
> device disabled. ata_dev_init_cdl_resources() is called from
> ata_dev_config_cdl() only for devices that support CDL.
> ata_dev_cleanup_cdl_resources() is called from ata_dev_free_resources()
> to free the ata_cdl structure when a device is being disabled by EH.
> 
> Note that the name of the former cdl log buffer of struct ata_device is
> changed to desc_log_buf to make it clearer that it is a buffer for the
> limit descriptors log page.
> 
> This change reduces the size of struct ata_device, thus reducing memory
> usage for ATA devices that do not support the CDL feature.
> 
> Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
> ---
>  drivers/ata/libata-core.c | 60 +++++++++++++++++++++++----------------
>  drivers/ata/libata-sata.c |  2 +-
>  drivers/ata/libata-scsi.c |  2 +-
>  drivers/ata/libata.h      |  1 +
>  include/linux/libata.h    | 21 +++++++++++---
>  5 files changed, 56 insertions(+), 30 deletions(-)
> 
> diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
> index bfd452b0d46d..bd2f8e442b14 100644
> --- a/drivers/ata/libata-core.c
> +++ b/drivers/ata/libata-core.c
> @@ -2464,12 +2464,40 @@ static void ata_dev_config_trusted(struct ata_device *dev)
>  		dev->flags |= ATA_DFLAG_TRUSTED;
>  }
>  
> +static int ata_dev_init_cdl_resources(struct ata_device *dev)
> +{
> +	struct ata_cdl *cdl = dev->cdl;
> +	unsigned int err_mask;
> +
> +	if (!cdl) {
> +		cdl = kzalloc(sizeof(*cdl), GFP_KERNEL);
> +		if (!cdl)
> +			return -ENOMEM;
> +		dev->cdl = cdl;
> +	}
> +
> +	err_mask = ata_read_log_page(dev, ATA_LOG_CDL, 0, cdl->desc_log_buf,
> +				     ATA_LOG_CDL_SIZE / ATA_SECT_SIZE);
> +	if (err_mask) {
> +		ata_dev_warn(dev, "Read Command Duration Limits log failed\n");
> +		return -EIO;

Usually when a function return error, you expect it to have freed the
resources that it might have allocated, so perhaps free and set
dev->cdl to NULL here.


> +	}
> +
> +	return 0;
> +}
> +
> +void ata_dev_cleanup_cdl_resources(struct ata_device *dev)
> +{
> +	kfree(dev->cdl);
> +	dev->cdl = NULL;
> +}
> +
>  static void ata_dev_config_cdl(struct ata_device *dev)
>  {
> -	struct ata_port *ap = dev->link->ap;
>  	unsigned int err_mask;
>  	bool cdl_enabled;
>  	u64 val;
> +	int ret;
>  
>  	if (ata_id_major_version(dev->id) < 11)
>  		goto not_supported;
> @@ -2564,37 +2592,20 @@ static void ata_dev_config_cdl(struct ata_device *dev)
>  		}
>  	}
>  
> -	/*
> -	 * Allocate a buffer to handle reading the sense data for successful
> -	 * NCQ Commands log page for commands using a CDL with one of the limit
> -	 * policy set to 0xD (successful completion with sense data available
> -	 * bit set).
> -	 */
> -	if (!ap->ncq_sense_buf) {
> -		ap->ncq_sense_buf = kmalloc(ATA_LOG_SENSE_NCQ_SIZE, GFP_KERNEL);
> -		if (!ap->ncq_sense_buf)
> -			goto not_supported;
> -	}
> -
> -	/*
> -	 * Command duration limits is supported: cache the CDL log page 18h
> -	 * (command duration descriptors).
> -	 */
> -	err_mask = ata_read_log_page(dev, ATA_LOG_CDL, 0, dev->sector_buf, 1);
> -	if (err_mask) {
> -		ata_dev_warn(dev, "Read Command Duration Limits log failed\n");
> +	/* CDL is supported: allocate and initialize needed resources. */
> +	ret = ata_dev_init_cdl_resources(dev);
> +	if (ret) {
> +		ata_dev_warn(dev, "Initialize CDL resources failed\n");
>  		goto not_supported;
>  	}
>  
> -	memcpy(dev->cdl, dev->sector_buf, ATA_LOG_CDL_SIZE);
>  	dev->flags |= ATA_DFLAG_CDL;
>  
>  	return;
>  
>  not_supported:
>  	dev->flags &= ~(ATA_DFLAG_CDL | ATA_DFLAG_CDL_ENABLED);
> -	kfree(ap->ncq_sense_buf);
> -	ap->ncq_sense_buf = NULL;
> +	ata_dev_cleanup_cdl_resources(dev);

Considering that you now do ata_dev_init_cdl_resources() at the end,
if you implement my suggestion above, we can remove the call to
ata_dev_cleanup_cdl_resources() here, since we will only jump here
if the ata_dev_init_cdl_resources() call failed.

Either way:
Reviewed-by: Niklas Cassel <cassel@kernel.org>


>  }
>  
>  static int ata_dev_config_lba(struct ata_device *dev)

  reply	other threads:[~2024-09-06  8:51 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-09-06  1:58 [PATCH v5 0/9] Code cleanup and memory usage reduction Damien Le Moal
2024-09-06  1:58 ` [PATCH v5 1/9] ata: libata: Cleanup libata-transport Damien Le Moal
2024-09-06  1:58 ` [PATCH v5 2/9] ata: libata-scsi: Improve ata_scsi_handle_link_detach() Damien Le Moal
2024-09-06  8:32   ` Niklas Cassel
2024-09-06  1:58 ` [PATCH v5 3/9] ata: libata: Improve __ata_qc_complete() Damien Le Moal
2024-09-06  1:58 ` [PATCH v5 4/9] ata: libata: Move sata_down_spd_limit() to libata-sata.c Damien Le Moal
2024-09-06  1:58 ` [PATCH v5 5/9] ata: libata: Move sata_std_hardreset() definition " Damien Le Moal
2024-09-06  1:58 ` [PATCH v5 6/9] ata: libata: Rename ata_eh_read_sense_success_ncq_log() Damien Le Moal
2024-09-06  1:58 ` [PATCH v5 7/9] ata: libata: Move sector_buf from struct ata_port to struct ata_device Damien Le Moal
2024-09-06  1:58 ` [PATCH v5 8/9] ata: libata: Introduce ata_dev_free_resources Damien Le Moal
2024-09-06  8:41   ` Niklas Cassel
2024-09-06  1:58 ` [PATCH v5 9/9] ata: libata: Improve CDL resource management Damien Le Moal
2024-09-06  8:51   ` Niklas Cassel [this message]
2024-09-06 10:21     ` Damien Le Moal

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ZtrCnMOLAfR5uoUz@ryzen.lan \
    --to=cassel@kernel.org \
    --cc=dlemoal@kernel.org \
    --cc=linux-ide@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.