Skip to content

Commit dc6a78f

Browse files
rddunlapJames Bottomley
authored andcommitted
[SCSI] atp870u: reduce huge stack usage
The atp870u driver is the largest stack eater reported by checkstack (on x86_864, allmodconfig). This converts the offending function to kmalloc+kfree struct atp_unit instead of allocating it on the stack. Was: 0x0000164c atp870u_probe [atp870u]: 3176 Now: 0x0000164c atp870u_probe [atp870u]: 408 Signed-off-by: Randy Dunlap <rdunlap@xenotime.net> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
1 parent 87cf898 commit dc6a78f

File tree

1 file changed

+83
-74
lines changed

1 file changed

+83
-74
lines changed

drivers/scsi/atp870u.c

Lines changed: 83 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -2625,29 +2625,32 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
26252625
unsigned int base_io, tmport, error,n;
26262626
unsigned char host_id;
26272627
struct Scsi_Host *shpnt = NULL;
2628-
struct atp_unit atp_dev, *p;
2628+
struct atp_unit *atpdev, *p;
26292629
unsigned char setupdata[2][16];
26302630
int count = 0;
2631-
2631+
2632+
atpdev = kzalloc(sizeof(*atpdev), GFP_KERNEL);
2633+
if (!atpdev)
2634+
return -ENOMEM;
2635+
26322636
if (pci_enable_device(pdev))
2633-
return -EIO;
2637+
goto err_eio;
26342638

26352639
if (!pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
26362640
printk(KERN_INFO "atp870u: use 32bit DMA mask.\n");
26372641
} else {
26382642
printk(KERN_ERR "atp870u: DMA mask required but not available.\n");
2639-
return -EIO;
2643+
goto err_eio;
26402644
}
26412645

2642-
memset(&atp_dev, 0, sizeof atp_dev);
26432646
/*
26442647
* It's probably easier to weed out some revisions like
26452648
* this than via the PCI device table
26462649
*/
26472650
if (ent->device == PCI_DEVICE_ID_ARTOP_AEC7610) {
2648-
error = pci_read_config_byte(pdev, PCI_CLASS_REVISION, &atp_dev.chip_ver);
2649-
if (atp_dev.chip_ver < 2)
2650-
return -EIO;
2651+
error = pci_read_config_byte(pdev, PCI_CLASS_REVISION, &atpdev->chip_ver);
2652+
if (atpdev->chip_ver < 2)
2653+
goto err_eio;
26512654
}
26522655

26532656
switch (ent->device) {
@@ -2656,33 +2659,33 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
26562659
case ATP880_DEVID1:
26572660
case ATP880_DEVID2:
26582661
case ATP885_DEVID:
2659-
atp_dev.chip_ver = 0x04;
2662+
atpdev->chip_ver = 0x04;
26602663
default:
26612664
break;
26622665
}
26632666
base_io = pci_resource_start(pdev, 0);
26642667
base_io &= 0xfffffff8;
2665-
2668+
26662669
if ((ent->device == ATP880_DEVID1)||(ent->device == ATP880_DEVID2)) {
2667-
error = pci_read_config_byte(pdev, PCI_CLASS_REVISION, &atp_dev.chip_ver);
2670+
error = pci_read_config_byte(pdev, PCI_CLASS_REVISION, &atpdev->chip_ver);
26682671
pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x80);//JCC082803
26692672

26702673
host_id = inb(base_io + 0x39);
26712674
host_id >>= 0x04;
26722675

26732676
printk(KERN_INFO " ACARD AEC-67160 PCI Ultra3 LVD Host Adapter: %d"
26742677
" IO:%x, IRQ:%d.\n", count, base_io, pdev->irq);
2675-
atp_dev.ioport[0] = base_io + 0x40;
2676-
atp_dev.pciport[0] = base_io + 0x28;
2677-
atp_dev.dev_id = ent->device;
2678-
atp_dev.host_id[0] = host_id;
2678+
atpdev->ioport[0] = base_io + 0x40;
2679+
atpdev->pciport[0] = base_io + 0x28;
2680+
atpdev->dev_id = ent->device;
2681+
atpdev->host_id[0] = host_id;
26792682

26802683
tmport = base_io + 0x22;
2681-
atp_dev.scam_on = inb(tmport);
2684+
atpdev->scam_on = inb(tmport);
26822685
tmport += 0x13;
2683-
atp_dev.global_map[0] = inb(tmport);
2686+
atpdev->global_map[0] = inb(tmport);
26842687
tmport += 0x07;
2685-
atp_dev.ultra_map[0] = inw(tmport);
2688+
atpdev->ultra_map[0] = inw(tmport);
26862689

26872690
n = 0x3f09;
26882691
next_fblk_880:
@@ -2695,57 +2698,57 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
26952698
if (inb(base_io + 0x30) == 0xff)
26962699
goto flash_ok_880;
26972700

2698-
atp_dev.sp[0][m++] = inb(base_io + 0x30);
2699-
atp_dev.sp[0][m++] = inb(base_io + 0x31);
2700-
atp_dev.sp[0][m++] = inb(base_io + 0x32);
2701-
atp_dev.sp[0][m++] = inb(base_io + 0x33);
2701+
atpdev->sp[0][m++] = inb(base_io + 0x30);
2702+
atpdev->sp[0][m++] = inb(base_io + 0x31);
2703+
atpdev->sp[0][m++] = inb(base_io + 0x32);
2704+
atpdev->sp[0][m++] = inb(base_io + 0x33);
27022705
outw(n, base_io + 0x34);
27032706
n += 0x0002;
2704-
atp_dev.sp[0][m++] = inb(base_io + 0x30);
2705-
atp_dev.sp[0][m++] = inb(base_io + 0x31);
2706-
atp_dev.sp[0][m++] = inb(base_io + 0x32);
2707-
atp_dev.sp[0][m++] = inb(base_io + 0x33);
2707+
atpdev->sp[0][m++] = inb(base_io + 0x30);
2708+
atpdev->sp[0][m++] = inb(base_io + 0x31);
2709+
atpdev->sp[0][m++] = inb(base_io + 0x32);
2710+
atpdev->sp[0][m++] = inb(base_io + 0x33);
27082711
outw(n, base_io + 0x34);
27092712
n += 0x0002;
2710-
atp_dev.sp[0][m++] = inb(base_io + 0x30);
2711-
atp_dev.sp[0][m++] = inb(base_io + 0x31);
2712-
atp_dev.sp[0][m++] = inb(base_io + 0x32);
2713-
atp_dev.sp[0][m++] = inb(base_io + 0x33);
2713+
atpdev->sp[0][m++] = inb(base_io + 0x30);
2714+
atpdev->sp[0][m++] = inb(base_io + 0x31);
2715+
atpdev->sp[0][m++] = inb(base_io + 0x32);
2716+
atpdev->sp[0][m++] = inb(base_io + 0x33);
27142717
outw(n, base_io + 0x34);
27152718
n += 0x0002;
2716-
atp_dev.sp[0][m++] = inb(base_io + 0x30);
2717-
atp_dev.sp[0][m++] = inb(base_io + 0x31);
2718-
atp_dev.sp[0][m++] = inb(base_io + 0x32);
2719-
atp_dev.sp[0][m++] = inb(base_io + 0x33);
2719+
atpdev->sp[0][m++] = inb(base_io + 0x30);
2720+
atpdev->sp[0][m++] = inb(base_io + 0x31);
2721+
atpdev->sp[0][m++] = inb(base_io + 0x32);
2722+
atpdev->sp[0][m++] = inb(base_io + 0x33);
27202723
n += 0x0018;
27212724
goto next_fblk_880;
27222725
flash_ok_880:
27232726
outw(0, base_io + 0x34);
2724-
atp_dev.ultra_map[0] = 0;
2725-
atp_dev.async[0] = 0;
2727+
atpdev->ultra_map[0] = 0;
2728+
atpdev->async[0] = 0;
27262729
for (k = 0; k < 16; k++) {
27272730
n = 1;
27282731
n = n << k;
2729-
if (atp_dev.sp[0][k] > 1) {
2730-
atp_dev.ultra_map[0] |= n;
2732+
if (atpdev->sp[0][k] > 1) {
2733+
atpdev->ultra_map[0] |= n;
27312734
} else {
2732-
if (atp_dev.sp[0][k] == 0)
2733-
atp_dev.async[0] |= n;
2735+
if (atpdev->sp[0][k] == 0)
2736+
atpdev->async[0] |= n;
27342737
}
27352738
}
2736-
atp_dev.async[0] = ~(atp_dev.async[0]);
2737-
outb(atp_dev.global_map[0], base_io + 0x35);
2739+
atpdev->async[0] = ~(atpdev->async[0]);
2740+
outb(atpdev->global_map[0], base_io + 0x35);
27382741

27392742
shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit));
27402743
if (!shpnt)
2741-
return -ENOMEM;
2744+
goto err_nomem;
27422745

27432746
p = (struct atp_unit *)&shpnt->hostdata;
27442747

2745-
atp_dev.host = shpnt;
2746-
atp_dev.pdev = pdev;
2748+
atpdev->host = shpnt;
2749+
atpdev->pdev = pdev;
27472750
pci_set_drvdata(pdev, p);
2748-
memcpy(p, &atp_dev, sizeof atp_dev);
2751+
memcpy(p, atpdev, sizeof(*atpdev));
27492752
if (atp870u_init_tables(shpnt) < 0) {
27502753
printk(KERN_ERR "Unable to allocate tables for Acard controller\n");
27512754
goto unregister;
@@ -2798,24 +2801,24 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
27982801
printk(KERN_INFO " ACARD AEC-67162 PCI Ultra3 LVD Host Adapter: IO:%x, IRQ:%d.\n"
27992802
, base_io, pdev->irq);
28002803

2801-
atp_dev.pdev = pdev;
2802-
atp_dev.dev_id = ent->device;
2803-
atp_dev.baseport = base_io;
2804-
atp_dev.ioport[0] = base_io + 0x80;
2805-
atp_dev.ioport[1] = base_io + 0xc0;
2806-
atp_dev.pciport[0] = base_io + 0x40;
2807-
atp_dev.pciport[1] = base_io + 0x50;
2804+
atpdev->pdev = pdev;
2805+
atpdev->dev_id = ent->device;
2806+
atpdev->baseport = base_io;
2807+
atpdev->ioport[0] = base_io + 0x80;
2808+
atpdev->ioport[1] = base_io + 0xc0;
2809+
atpdev->pciport[0] = base_io + 0x40;
2810+
atpdev->pciport[1] = base_io + 0x50;
28082811

28092812
shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit));
28102813
if (!shpnt)
2811-
return -ENOMEM;
2814+
goto err_nomem;
28122815

28132816
p = (struct atp_unit *)&shpnt->hostdata;
28142817

2815-
atp_dev.host = shpnt;
2816-
atp_dev.pdev = pdev;
2818+
atpdev->host = shpnt;
2819+
atpdev->pdev = pdev;
28172820
pci_set_drvdata(pdev, p);
2818-
memcpy(p, &atp_dev, sizeof(struct atp_unit));
2821+
memcpy(p, atpdev, sizeof(struct atp_unit));
28192822
if (atp870u_init_tables(shpnt) < 0)
28202823
goto unregister;
28212824

@@ -2974,33 +2977,33 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
29742977
printk(KERN_INFO " ACARD AEC-671X PCI Ultra/W SCSI-2/3 Host Adapter: %d "
29752978
"IO:%x, IRQ:%d.\n", count, base_io, pdev->irq);
29762979

2977-
atp_dev.ioport[0] = base_io;
2978-
atp_dev.pciport[0] = base_io + 0x20;
2979-
atp_dev.dev_id = ent->device;
2980+
atpdev->ioport[0] = base_io;
2981+
atpdev->pciport[0] = base_io + 0x20;
2982+
atpdev->dev_id = ent->device;
29802983
host_id &= 0x07;
2981-
atp_dev.host_id[0] = host_id;
2984+
atpdev->host_id[0] = host_id;
29822985
tmport = base_io + 0x22;
2983-
atp_dev.scam_on = inb(tmport);
2986+
atpdev->scam_on = inb(tmport);
29842987
tmport += 0x0b;
2985-
atp_dev.global_map[0] = inb(tmport++);
2986-
atp_dev.ultra_map[0] = inw(tmport);
2988+
atpdev->global_map[0] = inb(tmport++);
2989+
atpdev->ultra_map[0] = inw(tmport);
29872990

2988-
if (atp_dev.ultra_map[0] == 0) {
2989-
atp_dev.scam_on = 0x00;
2990-
atp_dev.global_map[0] = 0x20;
2991-
atp_dev.ultra_map[0] = 0xffff;
2991+
if (atpdev->ultra_map[0] == 0) {
2992+
atpdev->scam_on = 0x00;
2993+
atpdev->global_map[0] = 0x20;
2994+
atpdev->ultra_map[0] = 0xffff;
29922995
}
29932996

29942997
shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit));
29952998
if (!shpnt)
2996-
return -ENOMEM;
2999+
goto err_nomem;
29973000

29983001
p = (struct atp_unit *)&shpnt->hostdata;
29993002

3000-
atp_dev.host = shpnt;
3001-
atp_dev.pdev = pdev;
3003+
atpdev->host = shpnt;
3004+
atpdev->pdev = pdev;
30023005
pci_set_drvdata(pdev, p);
3003-
memcpy(p, &atp_dev, sizeof atp_dev);
3006+
memcpy(p, atpdev, sizeof(*atpdev));
30043007
if (atp870u_init_tables(shpnt) < 0)
30053008
goto unregister;
30063009

@@ -3010,7 +3013,7 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
30103013
}
30113014

30123015
spin_lock_irqsave(shpnt->host_lock, flags);
3013-
if (atp_dev.chip_ver > 0x07) { /* check if atp876 chip then enable terminator */
3016+
if (atpdev->chip_ver > 0x07) { /* check if atp876 chip then enable terminator */
30143017
tmport = base_io + 0x3e;
30153018
outb(0x00, tmport);
30163019
}
@@ -3044,7 +3047,7 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
30443047
outb((inb(tmport) & 0xef), tmport);
30453048
tmport++;
30463049
outb((inb(tmport) | 0x20), tmport);
3047-
if (atp_dev.chip_ver == 4)
3050+
if (atpdev->chip_ver == 4)
30483051
shpnt->max_id = 16;
30493052
else
30503053
shpnt->max_id = 8;
@@ -3093,6 +3096,12 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
30933096
printk("atp870u_prob:unregister\n");
30943097
scsi_host_put(shpnt);
30953098
return -1;
3099+
err_eio:
3100+
kfree(atpdev);
3101+
return -EIO;
3102+
err_nomem:
3103+
kfree(atpdev);
3104+
return -ENOMEM;
30963105
}
30973106

30983107
/* The abort command does not leave the device in a clean state where

0 commit comments

Comments
 (0)