* [PATCH] Stop using num_physpages in aacraid
@ 2008-05-02 18:52 Matthew Wilcox
2008-05-02 19:06 ` Mark Salyzyn
2008-05-02 19:45 ` Mark Salyzyn
0 siblings, 2 replies; 9+ messages in thread
From: Matthew Wilcox @ 2008-05-02 18:52 UTC (permalink / raw)
To: Mark Salyzyn; +Cc: linux-scsi
The num_physpages variable has an interesting and varied definition
depending on the architecture and various CONFIG options, not to mention
whether memory has been hotplugged or not. At any rate, it doesn't do
what aacraid is trying to use it for -- to determine whether a dma will
be 64-bit.
This patch removes the aac_scsi_32_64() function altogether, favouring
a failure to initialise over failing every command sent to the device.
The various quirks, options and flags are quite confusing. I think I've
managed to get it right, but I have no hardware to test with.
My understanding:
AAC_QUIRK_SCSI_32 means "This card cannot address above 64-bit.
But it does support the 64-bit format."
AAC_OPT_SGMAP_HOST64 means "This card MUST do DAC".
The patch below is intended to reflect that understanding. If I've
misunderstood the old code, or that wasn't what the old code was supposed
to mean then the below patch is wrong.
Signed-off-by: Matthew Wilcox <willy@linux.intel.com>
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
index 460d402..95e524a 100644
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -1199,15 +1199,6 @@ static int aac_scsi_32(struct fib * fib, struct scsi_cmnd * cmd)
(fib_callback) aac_srb_callback, (void *) cmd);
}
-static int aac_scsi_32_64(struct fib * fib, struct scsi_cmnd * cmd)
-{
- if ((sizeof(dma_addr_t) > 4) &&
- (num_physpages > (0xFFFFFFFFULL >> PAGE_SHIFT)) &&
- (fib->dev->adapter_info.options & AAC_OPT_SGMAP_HOST64))
- return FAILED;
- return aac_scsi_32(fib, cmd);
-}
-
int aac_get_adapter_info(struct aac_dev* dev)
{
struct fib* fibptr;
@@ -1367,26 +1358,36 @@ int aac_get_adapter_info(struct aac_dev* dev)
printk(KERN_INFO "%s%d: Non-DASD support enabled.\n",dev->name, dev->id);
dev->dac_support = 0;
- if( (sizeof(dma_addr_t) > 4) && (dev->adapter_info.options & AAC_OPT_SGMAP_HOST64)){
+ if ((sizeof(dma_addr_t) > 4) &&
+ (dev->adapter_info.options & AAC_OPT_SGMAP_HOST64)) {
if (!dev->in_reset)
printk(KERN_INFO "%s%d: 64bit support enabled.\n",
dev->name, dev->id);
dev->dac_support = 1;
}
- if(dacmode != -1) {
+ if (dacmode != -1) {
dev->dac_support = (dacmode!=0);
}
- if(dev->dac_support != 0) {
+ if (dev->dac_support &&
+ !(aac_get_driver_ident(dev->cardtype)->quirks &
+ AAC_QUIRK_SCSI_32)) {
if (!pci_set_dma_mask(dev->pdev, DMA_64BIT_MASK) &&
- !pci_set_consistent_dma_mask(dev->pdev, DMA_64BIT_MASK)) {
+ !pci_set_consistent_dma_mask(dev->pdev, DMA_64BIT_MASK)) {
if (!dev->in_reset)
printk(KERN_INFO"%s%d: 64 Bit DAC enabled\n",
dev->name, dev->id);
} else if (!pci_set_dma_mask(dev->pdev, DMA_32BIT_MASK) &&
- !pci_set_consistent_dma_mask(dev->pdev, DMA_32BIT_MASK)) {
+ !pci_set_consistent_dma_mask(dev->pdev,
+ DMA_32BIT_MASK)) {
printk(KERN_INFO"%s%d: DMA mask set failed, 64 Bit DAC disabled\n",
dev->name, dev->id);
+ if (dev->adapter_info.options & AAC_OPT_SGMAP_HOST64) {
+ printk(KERN_INFO "%s%d: 64-bit DAC required "
+ "for this host, bailing out\n",
+ dev->name, dev->id);
+ rcode = -ENOMEM;
+ }
dev->dac_support = 0;
} else {
printk(KERN_WARNING"%s%d: No suitable DMA available.\n",
@@ -1398,11 +1399,7 @@ int aac_get_adapter_info(struct aac_dev* dev)
* Deal with configuring for the individualized limits of each packet
* interface.
*/
- dev->a_ops.adapter_scsi = (dev->dac_support)
- ? ((aac_get_driver_ident(dev->cardtype)->quirks & AAC_QUIRK_SCSI_32)
- ? aac_scsi_32_64
- : aac_scsi_64)
- : aac_scsi_32;
+ dev->a_ops.adapter_scsi = dev->dac_support ? aac_scsi_64 : aac_scsi_32;
if (dev->raw_io_interface) {
dev->a_ops.adapter_bounds = (dev->raw_io_64)
? aac_bounds_64
--
Intel are signing my paycheques ... these opinions are still mine
"Bill, look, we understand that you're interested in selling us this
operating system, but compare it to ours. We can't possibly take such
a retrograde step."
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH] Stop using num_physpages in aacraid
2008-05-02 18:52 [PATCH] Stop using num_physpages in aacraid Matthew Wilcox
@ 2008-05-02 19:06 ` Mark Salyzyn
2008-05-03 10:51 ` Matthew Wilcox
2008-05-02 19:45 ` Mark Salyzyn
1 sibling, 1 reply; 9+ messages in thread
From: Mark Salyzyn @ 2008-05-02 19:06 UTC (permalink / raw)
To: Matthew Wilcox; +Cc: linux-scsi@vger.kernel.org
The num_physpages variable works as needed for the PERC controllers
that are installed in vanilla x86 machines is it not? The PERC card
would not be installed in any other arch.
AAC_QUIRK_SCSI_32 means the card can not send 64bit format commands to
the SCSI devices (non DASD) but can send 64bit format commands to the
logical (Array) devices. This is for a select set of old PERC cards.
AAC_OPT_SGMAP_HOST64 means this card 'can' do DAC (send 64 bit format
commands to both SCSI and to Array devices), but sadly some that
report this are borken (hence the Quirk AAC_QUIRK_SCSI_32).
Dropping the cards is not an option, that is the whole reason this
workaround was put in place.
I can handle dropping these select PERC cards from the list if the
architecture was NOT x86, since that was never a supported
architecture for these cards, but I am sure some folks are using them
this way ;-} I would prefer to DROP Non-DASD support for these cards
in 64 bit kernels if one is not to use num_physpages!
Sincerely -- Mark Salyzyn
On May 2, 2008, at 2:52 PM, Matthew Wilcox wrote:
>
> The num_physpages variable has an interesting and varied definition
> depending on the architecture and various CONFIG options, not to
> mention
> whether memory has been hotplugged or not. At any rate, it doesn't do
> what aacraid is trying to use it for -- to determine whether a dma
> will
> be 64-bit.
>
> This patch removes the aac_scsi_32_64() function altogether, favouring
> a failure to initialise over failing every command sent to the device.
>
> The various quirks, options and flags are quite confusing. I think
> I've
> managed to get it right, but I have no hardware to test with.
>
> My understanding:
> AAC_QUIRK_SCSI_32 means "This card cannot address above 64-bit.
> But it does support the 64-bit format."
>
> AAC_OPT_SGMAP_HOST64 means "This card MUST do DAC".
>
> The patch below is intended to reflect that understanding. If I've
> misunderstood the old code, or that wasn't what the old code was
> supposed
> to mean then the below patch is wrong.
>
> Signed-off-by: Matthew Wilcox <willy@linux.intel.com>
>
> diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/
> aachba.c
> index 460d402..95e524a 100644
> --- a/drivers/scsi/aacraid/aachba.c
> +++ b/drivers/scsi/aacraid/aachba.c
> @@ -1199,15 +1199,6 @@ static int aac_scsi_32(struct fib * fib,
> struct scsi_cmnd * cmd)
> (fib_callback) aac_srb_callback,
> (void *) cmd);
> }
>
> -static int aac_scsi_32_64(struct fib * fib, struct scsi_cmnd * cmd)
> -{
> - if ((sizeof(dma_addr_t) > 4) &&
> - (num_physpages > (0xFFFFFFFFULL >> PAGE_SHIFT)) &&
> - (fib->dev->adapter_info.options & AAC_OPT_SGMAP_HOST64))
> - return FAILED;
> - return aac_scsi_32(fib, cmd);
> -}
> -
> int aac_get_adapter_info(struct aac_dev* dev)
> {
> struct fib* fibptr;
> @@ -1367,26 +1358,36 @@ int aac_get_adapter_info(struct aac_dev* dev)
> printk(KERN_INFO "%s%d: Non-DASD support enabled.
> \n",dev->name, dev->id);
>
> dev->dac_support = 0;
> - if( (sizeof(dma_addr_t) > 4) && (dev->adapter_info.options &
> AAC_OPT_SGMAP_HOST64)){
> + if ((sizeof(dma_addr_t) > 4) &&
> + (dev->adapter_info.options & AAC_OPT_SGMAP_HOST64)) {
> if (!dev->in_reset)
> printk(KERN_INFO "%s%d: 64bit support enabled.
> \n",
> dev->name, dev->id);
> dev->dac_support = 1;
> }
>
> - if(dacmode != -1) {
> + if (dacmode != -1) {
> dev->dac_support = (dacmode!=0);
> }
> - if(dev->dac_support != 0) {
> + if (dev->dac_support &&
> + !(aac_get_driver_ident(dev->cardtype)->quirks &
> +
> AAC_QUIRK_SCSI_32)) {
> if (!pci_set_dma_mask(dev->pdev, DMA_64BIT_MASK) &&
> - !pci_set_consistent_dma_mask(dev->pdev,
> DMA_64BIT_MASK)) {
> + !pci_set_consistent_dma_mask(dev->pdev,
> DMA_64BIT_MASK)) {
> if (!dev->in_reset)
> printk(KERN_INFO"%s%d: 64 Bit DAC
> enabled\n",
> dev->name, dev->id);
> } else if (!pci_set_dma_mask(dev->pdev,
> DMA_32BIT_MASK) &&
> - !pci_set_consistent_dma_mask(dev->pdev,
> DMA_32BIT_MASK)) {
> + !pci_set_consistent_dma_mask(dev->pdev,
> +
> DMA_32BIT_MASK)) {
> printk(KERN_INFO"%s%d: DMA mask set failed,
> 64 Bit DAC disabled\n",
> dev->name, dev->id);
> + if (dev->adapter_info.options &
> AAC_OPT_SGMAP_HOST64) {
> + printk(KERN_INFO "%s%d: 64-bit DAC
> required "
> + "for this host, bailing out
> \n",
> + dev->name, dev->id);
> + rcode = -ENOMEM;
> + }
> dev->dac_support = 0;
> } else {
> printk(KERN_WARNING"%s%d: No suitable DMA
> available.\n",
> @@ -1398,11 +1399,7 @@ int aac_get_adapter_info(struct aac_dev* dev)
> * Deal with configuring for the individualized limits of
> each packet
> * interface.
> */
> - dev->a_ops.adapter_scsi = (dev->dac_support)
> - ? ((aac_get_driver_ident(dev->cardtype)->quirks &
> AAC_QUIRK_SCSI_32)
> - ? aac_scsi_32_64
> - : aac_scsi_64)
> - : aac_scsi_32;
> + dev->a_ops.adapter_scsi = dev->dac_support ? aac_scsi_64 :
> aac_scsi_32;
> if (dev->raw_io_interface) {
> dev->a_ops.adapter_bounds = (dev->raw_io_64)
> ? aac_bounds_64
>
> --
> Intel are signing my paycheques ... these opinions are still mine
> "Bill, look, we understand that you're interested in selling us this
> operating system, but compare it to ours. We can't possibly take such
> a retrograde step."
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] Stop using num_physpages in aacraid
2008-05-02 18:52 [PATCH] Stop using num_physpages in aacraid Matthew Wilcox
2008-05-02 19:06 ` Mark Salyzyn
@ 2008-05-02 19:45 ` Mark Salyzyn
1 sibling, 0 replies; 9+ messages in thread
From: Mark Salyzyn @ 2008-05-02 19:45 UTC (permalink / raw)
To: Matthew Wilcox; +Cc: linux-scsi@vger.kernel.org
As a follow up:
diff -ru a/aachba.c b/aachba.c
--- a/aachba.c 2008-05-02 15:35:39.227304669 -0400
+++ b/aachba.c 2008-05-02 15:36:07.450684444 -0400
@@ -1207,7 +1207,6 @@
static int aac_scsi_32_64(struct fib * fib, struct scsi_cmnd * cmd)
{
if ((sizeof(dma_addr_t) > 4) &&
- (num_physpages > (0xFFFFFFFFULL >> PAGE_SHIFT)) &&
(fib->dev->adapter_info.options & AAC_OPT_SGMAP_HOST64))
return FAILED;
return aac_scsi_32(fib, cmd);
will turn off NON-DASD (Tapes, CDROMS etc) support, and still enable
64 bit I/O on 64 bit operating systems to the Arrays on the defective
controllers. At least with the code before this change, we would allow
NON-DASD support if the memory did not hit the 32 bit boundary even if
it was a 64 bit OS.
One can switch to 32 bit I/O to the Arrays on 64 bit operating systems
and keep NON-DASD support:
diff -ru a/aachba.c b/aachba.c
--- a/aachba.c 2008-05-02 15:35:39.227304669 -0400
+++ b/aachba.c 2008-05-02 15:42:08.261039455 -0400
@@ -1204,15 +1204,6 @@
(fib_callback) aac_srb_callback,
(void *) cmd);
}
-static int aac_scsi_32_64(struct fib * fib, struct scsi_cmnd * cmd)
-{
- if ((sizeof(dma_addr_t) > 4) &&
- (num_physpages > (0xFFFFFFFFULL >> PAGE_SHIFT)) &&
- (fib->dev->adapter_info.options & AAC_OPT_SGMAP_HOST64))
- return FAILED;
- return aac_scsi_32(fib, cmd);
-}
-
int aac_get_adapter_info(struct aac_dev* dev)
{
struct fib* fibptr;
@@ -1382,6 +1373,8 @@
if(dacmode != -1) {
dev->dac_support = (dacmode!=0);
}
+ if (aac_get_driver_ident(dev->cardtype)->quirks &
AAC_QUIRK_SCSI_32)
+ dev->dac_support = 0;
if(dev->dac_support != 0) {
if (!pci_set_dma_mask(dev->pdev, DMA_64BIT_MASK) &&
!pci_set_consistent_dma_mask(dev->pdev,
DMA_64BIT_MASK)) {
@@ -1404,10 +1397,7 @@
* interface.
*/
dev->a_ops.adapter_scsi = (dev->dac_support)
- ? ((aac_get_driver_ident(dev->cardtype)->quirks &
AAC_QUIRK_SCSI_32)
- ? aac_scsi_32_64
- : aac_scsi_64)
- : aac_scsi_32;
+ ? aac_scsi_64 : aac_scsi_32;
if (dev->raw_io_interface) {
dev->a_ops.adapter_bounds = (dev->raw_io_64)
? aac_bounds_64
But you can not have BOTH, choose performance on Arrays, or NON-DASD
functionality.
Sincerely -- Mark Salyzyn
On May 2, 2008, at 2:52 PM, Matthew Wilcox wrote:
>
> The num_physpages variable has an interesting and varied definition
> depending on the architecture and various CONFIG options, not to
> mention
> whether memory has been hotplugged or not. At any rate, it doesn't do
> what aacraid is trying to use it for -- to determine whether a dma
> will
> be 64-bit.
>
> This patch removes the aac_scsi_32_64() function altogether, favouring
> a failure to initialise over failing every command sent to the device.
>
> The various quirks, options and flags are quite confusing. I think
> I've
> managed to get it right, but I have no hardware to test with.
>
> My understanding:
> AAC_QUIRK_SCSI_32 means "This card cannot address above 64-bit.
> But it does support the 64-bit format."
>
> AAC_OPT_SGMAP_HOST64 means "This card MUST do DAC".
>
> The patch below is intended to reflect that understanding. If I've
> misunderstood the old code, or that wasn't what the old code was
> supposed
> to mean then the below patch is wrong.
>
> Signed-off-by: Matthew Wilcox <willy@linux.intel.com>
>
> diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/
> aachba.c
> index 460d402..95e524a 100644
> --- a/drivers/scsi/aacraid/aachba.c
> +++ b/drivers/scsi/aacraid/aachba.c
> @@ -1199,15 +1199,6 @@ static int aac_scsi_32(struct fib * fib,
> struct scsi_cmnd * cmd)
> (fib_callback) aac_srb_callback,
> (void *) cmd);
> }
>
> -static int aac_scsi_32_64(struct fib * fib, struct scsi_cmnd * cmd)
> -{
> - if ((sizeof(dma_addr_t) > 4) &&
> - (num_physpages > (0xFFFFFFFFULL >> PAGE_SHIFT)) &&
> - (fib->dev->adapter_info.options & AAC_OPT_SGMAP_HOST64))
> - return FAILED;
> - return aac_scsi_32(fib, cmd);
> -}
> -
> int aac_get_adapter_info(struct aac_dev* dev)
> {
> struct fib* fibptr;
> @@ -1367,26 +1358,36 @@ int aac_get_adapter_info(struct aac_dev* dev)
> printk(KERN_INFO "%s%d: Non-DASD support enabled.
> \n",dev->name, dev->id);
>
> dev->dac_support = 0;
> - if( (sizeof(dma_addr_t) > 4) && (dev->adapter_info.options &
> AAC_OPT_SGMAP_HOST64)){
> + if ((sizeof(dma_addr_t) > 4) &&
> + (dev->adapter_info.options & AAC_OPT_SGMAP_HOST64)) {
> if (!dev->in_reset)
> printk(KERN_INFO "%s%d: 64bit support enabled.
> \n",
> dev->name, dev->id);
> dev->dac_support = 1;
> }
>
> - if(dacmode != -1) {
> + if (dacmode != -1) {
> dev->dac_support = (dacmode!=0);
> }
> - if(dev->dac_support != 0) {
> + if (dev->dac_support &&
> + !(aac_get_driver_ident(dev->cardtype)->quirks &
> +
> AAC_QUIRK_SCSI_32)) {
> if (!pci_set_dma_mask(dev->pdev, DMA_64BIT_MASK) &&
> - !pci_set_consistent_dma_mask(dev->pdev,
> DMA_64BIT_MASK)) {
> + !pci_set_consistent_dma_mask(dev->pdev,
> DMA_64BIT_MASK)) {
> if (!dev->in_reset)
> printk(KERN_INFO"%s%d: 64 Bit DAC
> enabled\n",
> dev->name, dev->id);
> } else if (!pci_set_dma_mask(dev->pdev,
> DMA_32BIT_MASK) &&
> - !pci_set_consistent_dma_mask(dev->pdev,
> DMA_32BIT_MASK)) {
> + !pci_set_consistent_dma_mask(dev->pdev,
> +
> DMA_32BIT_MASK)) {
> printk(KERN_INFO"%s%d: DMA mask set failed,
> 64 Bit DAC disabled\n",
> dev->name, dev->id);
> + if (dev->adapter_info.options &
> AAC_OPT_SGMAP_HOST64) {
> + printk(KERN_INFO "%s%d: 64-bit DAC
> required "
> + "for this host, bailing out
> \n",
> + dev->name, dev->id);
> + rcode = -ENOMEM;
> + }
> dev->dac_support = 0;
> } else {
> printk(KERN_WARNING"%s%d: No suitable DMA
> available.\n",
> @@ -1398,11 +1399,7 @@ int aac_get_adapter_info(struct aac_dev* dev)
> * Deal with configuring for the individualized limits of
> each packet
> * interface.
> */
> - dev->a_ops.adapter_scsi = (dev->dac_support)
> - ? ((aac_get_driver_ident(dev->cardtype)->quirks &
> AAC_QUIRK_SCSI_32)
> - ? aac_scsi_32_64
> - : aac_scsi_64)
> - : aac_scsi_32;
> + dev->a_ops.adapter_scsi = dev->dac_support ? aac_scsi_64 :
> aac_scsi_32;
> if (dev->raw_io_interface) {
> dev->a_ops.adapter_bounds = (dev->raw_io_64)
> ? aac_bounds_64
>
> --
> Intel are signing my paycheques ... these opinions are still mine
> "Bill, look, we understand that you're interested in selling us this
> operating system, but compare it to ours. We can't possibly take such
> a retrograde step."
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] Stop using num_physpages in aacraid
2008-05-02 19:06 ` Mark Salyzyn
@ 2008-05-03 10:51 ` Matthew Wilcox
2008-05-05 15:11 ` Mark Salyzyn
2008-05-08 21:18 ` James Bottomley
0 siblings, 2 replies; 9+ messages in thread
From: Matthew Wilcox @ 2008-05-03 10:51 UTC (permalink / raw)
To: Mark Salyzyn; +Cc: linux-scsi@vger.kernel.org
On Fri, May 02, 2008 at 03:06:42PM -0400, Mark Salyzyn wrote:
> The num_physpages variable works as needed for the PERC controllers
> that are installed in vanilla x86 machines is it not? The PERC card
> would not be installed in any other arch.
>
> AAC_QUIRK_SCSI_32 means the card can not send 64bit format commands to
> the SCSI devices (non DASD) but can send 64bit format commands to the
> logical (Array) devices. This is for a select set of old PERC cards.
>
> AAC_OPT_SGMAP_HOST64 means this card 'can' do DAC (send 64 bit format
> commands to both SCSI and to Array devices), but sadly some that
> report this are borken (hence the Quirk AAC_QUIRK_SCSI_32).
>
> Dropping the cards is not an option, that is the whole reason this
> workaround was put in place.
Thanks for the explanation of the quirks and options. I don't want to
drop support for any cards, I just want to make aacraid not rely on
the meaning of num_physpages.
The question aacraid wants to ask is "Does this device have to
do DAC to access memory?" The answer can be affected by an IOMMU or
by memory layout. It's far from clear what question num_physpages is
intended to answer; there are different bits of the kernel using it in
interesting ways. But we do have a function designed to answer the
question you want to ask: dma_get_required_mask(). This may be an
expensive question to ask, so in the below patch I cache the answer in
the aac_dev.
Signed-off-by: Matthew Wilcox <willy@linux.intel.com>
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
index 460d402..cd0865d 100644
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -1201,9 +1201,8 @@ static int aac_scsi_32(struct fib * fib, struct scsi_cmnd * cmd)
static int aac_scsi_32_64(struct fib * fib, struct scsi_cmnd * cmd)
{
- if ((sizeof(dma_addr_t) > 4) &&
- (num_physpages > (0xFFFFFFFFULL >> PAGE_SHIFT)) &&
- (fib->dev->adapter_info.options & AAC_OPT_SGMAP_HOST64))
+ if ((sizeof(dma_addr_t) > 4) && fib->dev->needs_dac &&
+ (fib->dev->adapter_info.options & AAC_OPT_SGMAP_HOST64))
return FAILED;
return aac_scsi_32(fib, cmd);
}
@@ -1394,6 +1393,9 @@ int aac_get_adapter_info(struct aac_dev* dev)
rcode = -ENOMEM;
}
}
+ if (dma_get_required_mask(&dev->pdev->dev) > DMA_32BIT_MASK)
+ dev->needs_dac = 1;
+
/*
* Deal with configuring for the individualized limits of each packet
* interface.
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index 113ca9c..a06c817 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -1016,6 +1016,7 @@ struct aac_dev
u8 jbod;
u8 cache_protected;
u8 dac_support;
+ u8 needs_dac;
u8 raid_scsi_mode;
u8 comm_interface;
# define AAC_COMM_PRODUCER 0
--
Intel are signing my paycheques ... these opinions are still mine
"Bill, look, we understand that you're interested in selling us this
operating system, but compare it to ours. We can't possibly take such
a retrograde step."
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH] Stop using num_physpages in aacraid
2008-05-03 10:51 ` Matthew Wilcox
@ 2008-05-05 15:11 ` Mark Salyzyn
2008-05-08 21:18 ` James Bottomley
1 sibling, 0 replies; 9+ messages in thread
From: Mark Salyzyn @ 2008-05-05 15:11 UTC (permalink / raw)
To: Matthew Wilcox; +Cc: linux-scsi@vger.kernel.org
Perfect! ACK!
Thanks for the suggestion.
Sincerely -- Mark Salyzyn
On May 3, 2008, at 6:51 AM, Matthew Wilcox wrote:
> . . .
> Thanks for the explanation of the quirks and options. I don't want to
> drop support for any cards, I just want to make aacraid not rely on
> the meaning of num_physpages.
>
> The question aacraid wants to ask is "Does this device have to
> do DAC to access memory?" The answer can be affected by an IOMMU or
> by memory layout. It's far from clear what question num_physpages is
> intended to answer; there are different bits of the kernel using it in
> interesting ways. But we do have a function designed to answer the
> question you want to ask: dma_get_required_mask(). This may be an
> expensive question to ask, so in the below patch I cache the answer in
> the aac_dev.
>
> Signed-off-by: Matthew Wilcox <willy@linux.intel.com>
>
> diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/
> aachba.c
> index 460d402..cd0865d 100644
> --- a/drivers/scsi/aacraid/aachba.c
> +++ b/drivers/scsi/aacraid/aachba.c
> @@ -1201,9 +1201,8 @@ static int aac_scsi_32(struct fib * fib,
> struct scsi_cmnd * cmd)
>
> static int aac_scsi_32_64(struct fib * fib, struct scsi_cmnd * cmd)
> {
> - if ((sizeof(dma_addr_t) > 4) &&
> - (num_physpages > (0xFFFFFFFFULL >> PAGE_SHIFT)) &&
> - (fib->dev->adapter_info.options & AAC_OPT_SGMAP_HOST64))
> + if ((sizeof(dma_addr_t) > 4) && fib->dev->needs_dac &&
> + (fib->dev->adapter_info.options & AAC_OPT_SGMAP_HOST64))
> return FAILED;
> return aac_scsi_32(fib, cmd);
> }
> @@ -1394,6 +1393,9 @@ int aac_get_adapter_info(struct aac_dev* dev)
> rcode = -ENOMEM;
> }
> }
> + if (dma_get_required_mask(&dev->pdev->dev) > DMA_32BIT_MASK)
> + dev->needs_dac = 1;
> +
> /*
> * Deal with configuring for the individualized limits of each packet
> * interface.
> diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/
> aacraid.h
> index 113ca9c..a06c817 100644
> --- a/drivers/scsi/aacraid/aacraid.h
> +++ b/drivers/scsi/aacraid/aacraid.h
> @@ -1016,6 +1016,7 @@ struct aac_dev
> u8 jbod;
> u8 cache_protected;
> u8 dac_support;
> + u8 needs_dac;
> u8 raid_scsi_mode;
> u8 comm_interface;
> # define AAC_COMM_PRODUCER 0
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] Stop using num_physpages in aacraid
2008-05-03 10:51 ` Matthew Wilcox
2008-05-05 15:11 ` Mark Salyzyn
@ 2008-05-08 21:18 ` James Bottomley
2008-05-09 6:39 ` Mark Salyzyn
1 sibling, 1 reply; 9+ messages in thread
From: James Bottomley @ 2008-05-08 21:18 UTC (permalink / raw)
To: Matthew Wilcox; +Cc: Mark Salyzyn, linux-scsi@vger.kernel.org
On Sat, 2008-05-03 at 04:51 -0600, Matthew Wilcox wrote:
> On Fri, May 02, 2008 at 03:06:42PM -0400, Mark Salyzyn wrote:
> > The num_physpages variable works as needed for the PERC controllers
> > that are installed in vanilla x86 machines is it not? The PERC card
> > would not be installed in any other arch.
> >
> > AAC_QUIRK_SCSI_32 means the card can not send 64bit format commands to
> > the SCSI devices (non DASD) but can send 64bit format commands to the
> > logical (Array) devices. This is for a select set of old PERC cards.
> >
> > AAC_OPT_SGMAP_HOST64 means this card 'can' do DAC (send 64 bit format
> > commands to both SCSI and to Array devices), but sadly some that
> > report this are borken (hence the Quirk AAC_QUIRK_SCSI_32).
> >
> > Dropping the cards is not an option, that is the whole reason this
> > workaround was put in place.
>
> Thanks for the explanation of the quirks and options. I don't want to
> drop support for any cards, I just want to make aacraid not rely on
> the meaning of num_physpages.
>
> The question aacraid wants to ask is "Does this device have to
> do DAC to access memory?" The answer can be affected by an IOMMU or
> by memory layout. It's far from clear what question num_physpages is
> intended to answer; there are different bits of the kernel using it in
> interesting ways. But we do have a function designed to answer the
> question you want to ask: dma_get_required_mask(). This may be an
> expensive question to ask, so in the below patch I cache the answer in
> the aac_dev.
Actually, I think we can do a bit better than this. We really only want
to enable 64 bit fibs if they're actually needed, so we should be
checking the dma_get_required_mask at all places the driver currently
looks for sizeof(dma_addr_t) > 4.
The attached, I think is cleaner (it also explains what this quirk is
for and calls the variable something more consonant with its function).
James
---
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
index aa4e77c..15e60cb 100644
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -1206,9 +1206,7 @@ static int aac_scsi_32(struct fib * fib, struct scsi_cmnd * cmd)
static int aac_scsi_32_64(struct fib * fib, struct scsi_cmnd * cmd)
{
- if ((sizeof(dma_addr_t) > 4) &&
- (num_physpages > (0xFFFFFFFFULL >> PAGE_SHIFT)) &&
- (fib->dev->adapter_info.options & AAC_OPT_SGMAP_HOST64))
+ if (fib->dev->no_scsi_64)
return FAILED;
return aac_scsi_32(fib, cmd);
}
@@ -1372,11 +1370,23 @@ int aac_get_adapter_info(struct aac_dev* dev)
printk(KERN_INFO "%s%d: Non-DASD support enabled.\n",dev->name, dev->id);
dev->dac_support = 0;
- if( (sizeof(dma_addr_t) > 4) && (dev->adapter_info.options & AAC_OPT_SGMAP_HOST64)){
+ if (dma_get_required_mask(&dev->pdev->dev) > DMA_32BIT_MASK
+ && (dev->adapter_info.options & AAC_OPT_SGMAP_HOST64)){
if (!dev->in_reset)
printk(KERN_INFO "%s%d: 64bit support enabled.\n",
dev->name, dev->id);
dev->dac_support = 1;
+
+ /*
+ * Adapters with AAC_QUIRK_SCSI_32 can only send pass
+ * through commands as 32 bit fibs (although they can
+ * send RAID commands as 64 bit fibs) flag these here
+ * so we fail direct SCSI commands in the special
+ * aac_scsi_32_64 routine
+ */
+ if (aac_get_driver_ident(dev->cardtype)->quirks
+ & AAC_QUIRK_SCSI_32)
+ dev->no_scsi_64 = 1;
}
if(dacmode != -1) {
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index 73916ad..39070c5 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -1020,6 +1020,7 @@ struct aac_dev
u8 jbod;
u8 cache_protected;
u8 dac_support;
+ u8 no_scsi_64;
u8 raid_scsi_mode;
u8 comm_interface;
# define AAC_COMM_PRODUCER 0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH] Stop using num_physpages in aacraid
2008-05-08 21:18 ` James Bottomley
@ 2008-05-09 6:39 ` Mark Salyzyn
2008-05-09 14:28 ` James Bottomley
2008-05-09 16:49 ` James Bottomley
0 siblings, 2 replies; 9+ messages in thread
From: Mark Salyzyn @ 2008-05-09 6:39 UTC (permalink / raw)
To: James Bottomley; +Cc: Matthew Wilcox, linux-scsi@vger.kernel.org
ACK
with comment, I had chosen to perform the sizeof check as it optimized
out the code on the 32 bit platforms and could have merged the
aac_scsi_32_64 and aac_scsi_32 functions (such considerations are my
penance for writing peephole optimizers and BIOS code in C/C++). Never
sacrifice clarity/maintainability for optimization if you can afford it.
Sincerely -- Mark Salyzyn
On May 8, 2008, at 5:18 PM, James Bottomley wrote:
> On Sat, 2008-05-03 at 04:51 -0600, Matthew Wilcox wrote:
>> On Fri, May 02, 2008 at 03:06:42PM -0400, Mark Salyzyn wrote:
>>> The num_physpages variable works as needed for the PERC controllers
>>> that are installed in vanilla x86 machines is it not? The PERC card
>>> would not be installed in any other arch.
>>>
>>> AAC_QUIRK_SCSI_32 means the card can not send 64bit format
>>> commands to
>>> the SCSI devices (non DASD) but can send 64bit format commands to
>>> the
>>> logical (Array) devices. This is for a select set of old PERC cards.
>>>
>>> AAC_OPT_SGMAP_HOST64 means this card 'can' do DAC (send 64 bit
>>> format
>>> commands to both SCSI and to Array devices), but sadly some that
>>> report this are borken (hence the Quirk AAC_QUIRK_SCSI_32).
>>>
>>> Dropping the cards is not an option, that is the whole reason this
>>> workaround was put in place.
>>
>> Thanks for the explanation of the quirks and options. I don't want
>> to
>> drop support for any cards, I just want to make aacraid not rely on
>> the meaning of num_physpages.
>>
>> The question aacraid wants to ask is "Does this device have to
>> do DAC to access memory?" The answer can be affected by an IOMMU or
>> by memory layout. It's far from clear what question num_physpages is
>> intended to answer; there are different bits of the kernel using it
>> in
>> interesting ways. But we do have a function designed to answer the
>> question you want to ask: dma_get_required_mask(). This may be an
>> expensive question to ask, so in the below patch I cache the answer
>> in
>> the aac_dev.
>
> Actually, I think we can do a bit better than this. We really only
> want
> to enable 64 bit fibs if they're actually needed, so we should be
> checking the dma_get_required_mask at all places the driver currently
> looks for sizeof(dma_addr_t) > 4.
>
> The attached, I think is cleaner (it also explains what this quirk is
> for and calls the variable something more consonant with its
> function).
>
> James
>
>
> ---
>
> diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/
> aachba.c
> index aa4e77c..15e60cb 100644
> --- a/drivers/scsi/aacraid/aachba.c
> +++ b/drivers/scsi/aacraid/aachba.c
> @@ -1206,9 +1206,7 @@ static int aac_scsi_32(struct fib * fib,
> struct scsi_cmnd * cmd)
>
> static int aac_scsi_32_64(struct fib * fib, struct scsi_cmnd * cmd)
> {
> - if ((sizeof(dma_addr_t) > 4) &&
> - (num_physpages > (0xFFFFFFFFULL >> PAGE_SHIFT)) &&
> - (fib->dev->adapter_info.options & AAC_OPT_SGMAP_HOST64))
> + if (fib->dev->no_scsi_64)
> return FAILED;
> return aac_scsi_32(fib, cmd);
> }
> @@ -1372,11 +1370,23 @@ int aac_get_adapter_info(struct aac_dev* dev)
> printk(KERN_INFO "%s%d: Non-DASD support enabled.
> \n",dev->name, dev->id);
>
> dev->dac_support = 0;
> - if( (sizeof(dma_addr_t) > 4) && (dev->adapter_info.options &
> AAC_OPT_SGMAP_HOST64)){
> + if (dma_get_required_mask(&dev->pdev->dev) > DMA_32BIT_MASK
> + && (dev->adapter_info.options & AAC_OPT_SGMAP_HOST64)){
> if (!dev->in_reset)
> printk(KERN_INFO "%s%d: 64bit support enabled.
> \n",
> dev->name, dev->id);
> dev->dac_support = 1;
> +
> + /*
> + * Adapters with AAC_QUIRK_SCSI_32 can only send pass
> + * through commands as 32 bit fibs (although they can
> + * send RAID commands as 64 bit fibs) flag these here
> + * so we fail direct SCSI commands in the special
> + * aac_scsi_32_64 routine
> + */
> + if (aac_get_driver_ident(dev->cardtype)->quirks
> + & AAC_QUIRK_SCSI_32)
> + dev->no_scsi_64 = 1;
> }
>
> if(dacmode != -1) {
> diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/
> aacraid.h
> index 73916ad..39070c5 100644
> --- a/drivers/scsi/aacraid/aacraid.h
> +++ b/drivers/scsi/aacraid/aacraid.h
> @@ -1020,6 +1020,7 @@ struct aac_dev
> u8 jbod;
> u8 cache_protected;
> u8 dac_support;
> + u8 no_scsi_64;
> u8 raid_scsi_mode;
> u8 comm_interface;
> # define AAC_COMM_PRODUCER 0
>
>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] Stop using num_physpages in aacraid
2008-05-09 6:39 ` Mark Salyzyn
@ 2008-05-09 14:28 ` James Bottomley
2008-05-09 16:49 ` James Bottomley
1 sibling, 0 replies; 9+ messages in thread
From: James Bottomley @ 2008-05-09 14:28 UTC (permalink / raw)
To: Mark Salyzyn; +Cc: Matthew Wilcox, linux-scsi@vger.kernel.org
On Fri, 2008-05-09 at 02:39 -0400, Mark Salyzyn wrote:
> ACK
>
> with comment, I had chosen to perform the sizeof check as it optimized
> out the code on the 32 bit platforms and could have merged the
> aac_scsi_32_64 and aac_scsi_32 functions (such considerations are my
> penance for writing peephole optimizers and BIOS code in C/C++). Never
> sacrifice clarity/maintainability for optimization if you can afford it.
Yes ... I wish there were some way of getting the
dma_get_required_mask() > DMA_32BIT_MASK
to compile out in the 32 bit case. I'll think about it.
Another thing to note is that your problem could be solved if we could
adjust the queue mask per device (you want a 64 bit mask for the raid
devices and a 32 bit one for the physical ones). This is analagous to
the ATA MDMA problem with ATA/ATAPI (the protocol can only do 32 bits
with ATAPI but the full 64 bits with ATA). I'll see if we can use this
as a case to drive a fix for that.
James
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] Stop using num_physpages in aacraid
2008-05-09 6:39 ` Mark Salyzyn
2008-05-09 14:28 ` James Bottomley
@ 2008-05-09 16:49 ` James Bottomley
1 sibling, 0 replies; 9+ messages in thread
From: James Bottomley @ 2008-05-09 16:49 UTC (permalink / raw)
To: Mark Salyzyn; +Cc: Matthew Wilcox, linux-scsi@vger.kernel.org
On Fri, 2008-05-09 at 02:39 -0400, Mark Salyzyn wrote:
> with comment, I had chosen to perform the sizeof check as it optimized
> out the code on the 32 bit platforms and could have merged the
> aac_scsi_32_64 and aac_scsi_32 functions (such considerations are my
> penance for writing peephole optimizers and BIOS code in C/C++). Never
> sacrifice clarity/maintainability for optimization if you can afford it.
Actually, point taken on the queuecommand check and the lesson in
optimisation. This should actually be a better optimised version,
getting rid of the check altogether.
James
---
From: James Bottomley <James.Bottomley@HansenPartnership.com>
Subject: [SCSI] aacraid: don't use num_physpages
aacraid uses num_physpages as a check to see if it needs to fail
commands to physical drives which can only be sent as 32 bit fibs for
certain cards (those with AAC_QUIRK_SCSI_32 set). The correct API for
this is dma_get_required_mask(), so make it use that. Also tidy up
the 64 bit fib enabling code so we only enable it if the kernel is 64
bit and the dma mask goes over 32 bits (i.e. it has memory above 4GB).
Acked-by: Mark Salyzyn <Mark_Salyzyn@adaptec.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
---
drivers/scsi/aacraid/aachba.c | 37 +++++++++++++++++++++++--------------
1 files changed, 23 insertions(+), 14 deletions(-)
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
index aa4e77c..2cc2c09 100644
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -1204,13 +1204,14 @@ static int aac_scsi_32(struct fib * fib, struct scsi_cmnd * cmd)
(fib_callback) aac_srb_callback, (void *) cmd);
}
+/*
+ * This routine is only used if we have memory > 4GB and the adapter
+ * is one of the quirky ones that can't do dma above 4GB to physical
+ * disks
+ */
static int aac_scsi_32_64(struct fib * fib, struct scsi_cmnd * cmd)
{
- if ((sizeof(dma_addr_t) > 4) &&
- (num_physpages > (0xFFFFFFFFULL >> PAGE_SHIFT)) &&
- (fib->dev->adapter_info.options & AAC_OPT_SGMAP_HOST64))
- return FAILED;
- return aac_scsi_32(fib, cmd);
+ return FAILED;
}
int aac_get_adapter_info(struct aac_dev* dev)
@@ -1372,16 +1373,29 @@ int aac_get_adapter_info(struct aac_dev* dev)
printk(KERN_INFO "%s%d: Non-DASD support enabled.\n",dev->name, dev->id);
dev->dac_support = 0;
- if( (sizeof(dma_addr_t) > 4) && (dev->adapter_info.options & AAC_OPT_SGMAP_HOST64)){
+ dev->a_ops.adapter_scsi = aac_scsi_32;
+ if ((dma_get_required_mask(&dev->pdev->dev) > DMA_32BIT_MASK
+ && (dev->adapter_info.options & AAC_OPT_SGMAP_HOST64)
+ && dacmode == -1) ||
+ dacmode == 1) {
if (!dev->in_reset)
printk(KERN_INFO "%s%d: 64bit support enabled.\n",
dev->name, dev->id);
dev->dac_support = 1;
- }
+ dev->a_ops.adapter_scsi = aac_scsi_64;
- if(dacmode != -1) {
- dev->dac_support = (dacmode!=0);
+ /*
+ * Adapters with AAC_QUIRK_SCSI_32 can only send pass
+ * through commands as 32 bit fibs (although they can
+ * send RAID commands as 64 bit fibs) flag these here
+ * so we fail direct SCSI commands in the special
+ * aac_scsi_32_64 routine
+ */
+ if (aac_get_driver_ident(dev->cardtype)->quirks
+ & AAC_QUIRK_SCSI_32)
+ dev->a_ops.adapter_scsi = aac_scsi_32_64;
}
+
if(dev->dac_support != 0) {
if (!pci_set_dma_mask(dev->pdev, DMA_64BIT_MASK) &&
!pci_set_consistent_dma_mask(dev->pdev, DMA_64BIT_MASK)) {
@@ -1403,11 +1417,6 @@ int aac_get_adapter_info(struct aac_dev* dev)
* Deal with configuring for the individualized limits of each packet
* interface.
*/
- dev->a_ops.adapter_scsi = (dev->dac_support)
- ? ((aac_get_driver_ident(dev->cardtype)->quirks & AAC_QUIRK_SCSI_32)
- ? aac_scsi_32_64
- : aac_scsi_64)
- : aac_scsi_32;
if (dev->raw_io_interface) {
dev->a_ops.adapter_bounds = (dev->raw_io_64)
? aac_bounds_64
--
1.5.4.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
end of thread, other threads:[~2008-05-09 16:49 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-05-02 18:52 [PATCH] Stop using num_physpages in aacraid Matthew Wilcox
2008-05-02 19:06 ` Mark Salyzyn
2008-05-03 10:51 ` Matthew Wilcox
2008-05-05 15:11 ` Mark Salyzyn
2008-05-08 21:18 ` James Bottomley
2008-05-09 6:39 ` Mark Salyzyn
2008-05-09 14:28 ` James Bottomley
2008-05-09 16:49 ` James Bottomley
2008-05-02 19:45 ` Mark Salyzyn
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox