Hello, all.
This patch is the result from the following discussion.
http://thread.gmane.org/gmane.linux.ide/16475
The problem is that CONFIG_PM affects a lot of low level drivers and
scattering CONFIG_PM all over the place is too ugly. This patch...
* implements __attribute_discard_text__ and __attribute_discard_data__
(not implemented for modules yet, only for built-ins)
* uses them to implement __pm and __pmdata markers
* convert libata midlayer and ahci to use it instead of CONFIG_PM
__attribute_discard_text/data__ puts the marked symbols in separate
sections which are located from VMA 0 and discarded when generating
the final image. It's similar to putting those into /DISCARD/ section
but won't complain even if the discarded symbols are referenced by
active sections. As the discard sections are located from VMA 0,
actually dereferencing such symbols will result in OOPS.
This trick certainly makes LLDs cleaner but there are also some
downsides, so here are the cons.
* Cannot depend on the compiler to detect illegal dereferences to
discarded symbols. We probably can do this using sparse.
* Cannot use the compiler to detect unused but unmarked symbols. This
also probably can be done with sparse.
* EXPORT_SYMBOL() is nullified, so it will take extra bytes for
each symbol marked with __pm. (insignificant)
* Implementation involves modifying kernel image, module build process
and possibly sparse. It might be too expensive to achieve device
driver prettiness, but there are a lot of device drivers out there
and a lot of CONFIG_PM's to be added. Also, discard attributes can
be used for other purposes too.
Any better ideas? Comments?
DO NOT APPLY.
diff --git a/arch/i386/Makefile b/arch/i386/Makefile
index bd28f9f..2806dfe 100644
--- a/arch/i386/Makefile
+++ b/arch/i386/Makefile
@@ -25,7 +25,7 @@ CC := $(CC) -m32
endif
LDFLAGS:= -m elf_i386
-OBJCOPYFLAGS := -O binary -R .note -R .comment -S
+OBJCOPYFLAGS := -O binary -R .note -R .comment -R .discard -S
ifdef CONFIG_RELOCATABLE
LDFLAGS_vmlinux := --emit-relocs
endif
diff --git a/arch/i386/kernel/vmlinux.lds.S b/arch/i386/kernel/vmlinux.lds.S
index ca51610..69b18c6 100644
--- a/arch/i386/kernel/vmlinux.lds.S
+++ b/arch/i386/kernel/vmlinux.lds.S
@@ -32,6 +32,7 @@ PHDRS {
text PT_LOAD FLAGS(5); /* R_E */
data PT_LOAD FLAGS(7); /* RWE */
note PT_NOTE FLAGS(4); /* R__ */
+ QUIET_DISCARD_PHDR
}
SECTIONS
{
@@ -217,6 +218,8 @@ SECTIONS
}
/* Sections to be discarded */
+ QUIET_DISCARD
+
/DISCARD/ : {
*(.exitcall.exit)
}
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 43cc43d..bfb0135 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -219,12 +219,10 @@ static void ahci_thaw(struct ata_port *ap);
static void ahci_error_handler(struct ata_port *ap);
static void ahci_vt8251_error_handler(struct ata_port *ap);
static void ahci_post_internal_cmd(struct ata_queued_cmd *qc);
-#ifdef CONFIG_PM
static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg);
static int ahci_port_resume(struct ata_port *ap);
static int ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg);
static int ahci_pci_device_resume(struct pci_dev *pdev);
-#endif
static struct scsi_host_template ahci_sht = {
.module = THIS_MODULE,
@@ -243,10 +241,8 @@ static struct scsi_host_template ahci_sht = {
.slave_configure= ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
.suspend= ata_scsi_device_suspend,
.resume = ata_scsi_device_resume,
-#endif
};
static const struct ata_port_operations ahci_ops = {
@@ -275,10 +271,8 @@ static const struct ata_port_operations ahci_ops = {
.error_handler = ahci_error_handler,
.post_internal_cmd = ahci_post_internal_cmd,
-#ifdef CONFIG_PM
.port_suspend = ahci_port_suspend,
.port_resume= ahci_port_resume,
-#endif
.port_start = ahci_port_start,
.port_stop = ahci_port_stop,
@@ -310,10 +304,8 @@ static const struct ata_port_operations ahci_vt8251_ops = {
.error_handler = ahci_vt8251_error_handler,
.post_internal_cmd = ahci_post_internal_cmd,
-#ifdef CONFIG_PM
.port_suspend = ahci_port_suspend,
.port_resume= ahci_port_resume,
-#endif
.port_start = ahci_port_start,
.port_stop = ahci_port_stop,
@@ -444,10 +436,8 @@ static struct pci_driver ahci_pci_driver = {
.id_table = ahci_pci_tbl,
.probe = ahci_init_one,
.remove = ata_pci_remove_one,
-#ifdef CONFIG_PM
.suspend= ahci_pci_device_suspend,