From: Robert Jennings <hidden> Date: 2008-07-23 18:19:39
This is version 4 of the full patchset pulling in all prior changes
posted to the list. Two patches sent separately to apply on top of the
prior set have been included in this set.
Cooperative Memory Overcommitment (CMO) is a pSeries platform feature
that enables the allocation of more memory to a set logical partitions
than is physically present. For example, a system with 16Gb of memory
can be configured to simultaneously run 3 logical partitions each with
8Gb of memory allocated to them.
The system firmware can page out memory as needed to meet the needs
of each partition. To minimize the effects of firmware paging memory,
the Collaborative Memory Manager (CMM) driver acts as a balloon driver
to work with firmware to provide memory ahead of any paging needs.
The OS is provided with an entitlement of IO memory for device drivers
to map. This amount varies with the number of virtual IO adapters
present and can change as devices are hot-plugged. The VIO bus code
distributes this memory to devices. Logical partitions supporting CMO
may only have virtual IO devices, physical devices are not supported.
Above the entitled level, IO mappings can fail and the IOMMU needed be
updated to handle this change.
Virtual IO adapters have been updated to handle DMA mapping failures and
to size their entitlement needs.
Platform support for for CMM and hot-plug entitlement events are also
included in the following patches.
The changes should have minimal impact to non-CMO enabled environments.
This patch set has been written against 2.6.26 and has been tested
at that level.
Regards,
Robert Jennings
From: Robert Jennings <hidden> Date: 2008-07-23 18:25:22
hering to helper routines
=46rom: Nathan Fotenot [off-list ref]
Split the retrieval and setting of processor entitlement and weight into
helper routines. This also removes the printing of the raw values
returned from h_get_ppp, the values are already parsed and printed.
Signed-off-by: Nathan Fontenot <redacted>
Signed-off-by: Robert Jennings <redacted>
---
Updated patch to remove checking the return code from the h_call for
H_PIC. This reverts the reporting back to its original state.
---
arch/powerpc/kernel/lparcfg.c | 166 ++++++++++++++++++++++---------------=
-----
1 file changed, 88 insertions(+), 78 deletions(-)
Index: b/arch/powerpc/kernel/lparcfg.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
@@ -167,7 +167,8 @@ static unsigned int h_get_ppp(unsigned lreturnrc;}
=20
-static void h_pic(unsigned long *pool_idle_time, unsigned long *num_procs)
+static unsigned h_pic(unsigned long *pool_idle_time,
+ unsigned long *num_procs)
{
unsigned long rc;
unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
@@ -176,6 +177,51 @@ static void h_pic(unsigned long *pool_id
@@ -351,6 +418,7 @@ static int pseries_lparcfg_data(struct s /* this call handles the ibm,get-system-parameter contents */ parse_system_parameter_string(m); parse_ppp_data(m);+ parse_mpp_data(m);
=20
seq_printf(m, "purr=3D%ld\n", get_purr());
} else { /* non SPLPAR case */
From: Robert Jennings <rcj@linux.vnet.ibm.com>,
Nathan Fontenot <nfont@austin.ibm.com> Date: 2008-07-23 18:28:11
Split the retrieval of processor entitlement data returned in the H_GET_PPP
hcall into its own helper routine.
Signed-off-by: Nathan Fontenot <redacted>
Signed-off-by: Robert Jennings <redacted>
---
Updated patch to correct the reporting of pool_capcity.
---
arch/powerpc/kernel/lparcfg.c | 81 ++++++++++++++++++++++++------------------
1 file changed, 46 insertions(+), 35 deletions(-)
Index: b/arch/powerpc/kernel/lparcfg.c
===================================================================
@@ -216,41 +232,40 @@ static unsigned h_pic(unsigned long *poo*/staticvoidparse_ppp_data(structseq_file*m){-unsignedlongh_entitled,h_unallocated;-unsignedlongh_aggregation,h_resource;+structhvcall_ppp_datappp_data;intrc;-rc=h_get_ppp(&h_entitled,&h_unallocated,&h_aggregation,-&h_resource);+rc=h_get_ppp(&ppp_data);if(rc)return;-seq_printf(m,"partition_entitled_capacity=%ld\n",h_entitled);-seq_printf(m,"group=%ld\n",(h_aggregation>>2*8)&0xffff);-seq_printf(m,"system_active_processors=%ld\n",-(h_resource>>0*8)&0xffff);+seq_printf(m,"partition_entitled_capacity=%ld\n",+ppp_data.entitlement);+seq_printf(m,"group=%d\n",ppp_data.group_num);+seq_printf(m,"system_active_processors=%d\n",+ppp_data.active_system_procs);/* pool related entries are apropriate for shared configs */if(lppaca[0].shared_proc){unsignedlongpool_idle_time,pool_procs;-seq_printf(m,"pool=%ld\n",(h_aggregation>>0*8)&0xffff);+seq_printf(m,"pool=%d\n",ppp_data.pool_num);/* report pool_capacity in percentage */-seq_printf(m,"pool_capacity=%ld\n",-((h_resource>>2*8)&0xffff)*100);+seq_printf(m,"pool_capacity=%d\n",+ppp_data.active_procs_in_pool*100);h_pic(&pool_idle_time,&pool_procs);seq_printf(m,"pool_idle_time=%ld\n",pool_idle_time);seq_printf(m,"pool_num_procs=%ld\n",pool_procs);}-seq_printf(m,"unallocated_capacity_weight=%ld\n",-(h_resource>>4*8)&0xFF);--seq_printf(m,"capacity_weight=%ld\n",(h_resource>>5*8)&0xFF);-seq_printf(m,"capped=%ld\n",(h_resource>>6*8)&0x01);-seq_printf(m,"unallocated_capacity=%ld\n",h_unallocated);+seq_printf(m,"unallocated_capacity_weight=%d\n",+ppp_data.unallocated_weight);+seq_printf(m,"capacity_weight=%d\n",ppp_data.weight);+seq_printf(m,"capped=%d\n",ppp_data.capped);+seq_printf(m,"unallocated_capacity=%ld\n",+ppp_data.unallocated_entitlement);}/**
@@ -449,31 +464,27 @@ static int pseries_lparcfg_data(struct sstaticssize_tupdate_ppp(u64*entitlement,u8*weight){-unsignedlongcurrent_entitled;-unsignedlongdummy;-unsignedlongresource;-u8current_weight,new_weight;+structhvcall_ppp_datappp_data;+u8new_weight;u64new_entitled;ssize_tretval;/* Get our current parameters */-retval=h_get_ppp(¤t_entitled,&dummy,&dummy,&resource);+retval=h_get_ppp(&ppp_data);if(retval)returnretval;-current_weight=(resource>>5*8)&0xFF;-if(entitlement){-new_weight=current_weight;+new_weight=ppp_data.weight;new_entitled=*entitlement;}elseif(weight){new_weight=*weight;-new_entitled=current_entitled;+new_entitled=ppp_data.entitlement;}elsereturn-EINVAL;pr_debug("%s: current_entitled = %lu, current_weight = %u\n",-__FUNCTION__,current_entitled,current_weight);+__FUNCTION__,ppp_data.entitlement,ppp_data.weight);pr_debug("%s: new_entitled = %lu, new_weight = %u\n",__FUNCTION__,new_entitled,new_weight);
From: Robert Jennings <hidden> Date: 2008-07-23 18:29:06
=46rom: Robert Jennings [off-list ref]
For Cooperative Memory Overcommitment (CMO), set the FW_FEATURE_CMO
flag in powerpc_firmware_features from the rtas ibm,get-system-parameters
table prior to calling iommu_init_early_pSeries.
With this, any CMO specific functionality can be controlled by checking:
firmware_has_feature(FW_FEATURE_CMO)
Signed-off-by: Robert Jennings <redacted>
---
Correct string conversion for rtas value being read for CMO configuration.
A value of -1 in the string indicates that CMO is not enabled and we
had used simple_strtoul rather than simple_strtol.
---
arch/powerpc/platforms/pseries/setup.c | 71 ++++++++++++++++++++++++++++=
+++++
include/asm-powerpc/firmware.h | 3 +
2 files changed, 73 insertions(+), 1 deletion(-)
Index: b/arch/powerpc/platforms/pseries/setup.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
From: Robert Jennings <hidden> Date: 2008-07-23 18:29:40
=46rom: Brian King [off-list ref]
Newer versions of firmware support page states, which are used by the
collaborative memory manager (future patch) to "loan" pages to the
hypervisor for use by other partitions.
Signed-off-by: Brian King <redacted>
Signed-off-by: Robert Jennings <redacted>
---
arch/powerpc/platforms/pseries/plpar_wrappers.h | 10 ++++++++++
include/asm-powerpc/hvcall.h | 5 +++++
2 files changed, 15 insertions(+)
Index: b/arch/powerpc/platforms/pseries/plpar_wrappers.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
@@ -92,6 +92,11 @@#define H_EXACT (1UL<<(63-24)) /* Use exact PTE or return H_PTEG_FULL */#define H_R_XLATE (1UL<<(63-25)) /* include a valid logical page num in t=
he pte if the valid bit is set */
#define H_READ_4 (1UL<<(63-26)) /* Return 4 PTEs */
+#define H_PAGE_STATE_CHANGE (1UL<<(63-28))
+#define H_PAGE_UNUSED ((1UL<<(63-29)) | (1UL<<(63-30)))
+#define H_PAGE_SET_UNUSED (H_PAGE_STATE_CHANGE | H_PAGE_UNUSED)
+#define H_PAGE_SET_LOANED (H_PAGE_SET_UNUSED | (1UL<<(63-31)))
+#define H_PAGE_SET_ACTIVE H_PAGE_STATE_CHANGE
#define H_AVPN (1UL<<(63-32)) /* An avpn is provided as a sanity test */
#define H_ANDCOND (1UL<<(63-33))
#define H_ICACHE_INVALIDATE (1UL<<(63-40)) /* icbi, etc. (ignored for IO =
pages) */
From: Robert Jennings <hidden> Date: 2008-07-23 18:30:33
=46rom: Brian King [off-list ref]
Adds a collaborative memory manager, which acts as a simple balloon driver
for System p machines that support cooperative memory overcommitment
(CMO).
Adds a platform configuration option for CMO called PPC_SMLPAR.
Signed-off-by: Brian King <redacted>
Signed-off-by: Robert Jennings <redacted>
---
Added a config option PPC_SMLPAR ("Support for shared-memory logical
partitions") to the platform. This will select LPARCFG and address the
issue where h_get_mpp() may not have been present when compiling. This
new config option is now used to #ifdef out code in the vio bus patch that
follows and the arch vector patch that enables the code for firmware.
---
arch/powerpc/platforms/pseries/Kconfig | 23 ++
arch/powerpc/platforms/pseries/Makefile | 1 +
arch/powerpc/platforms/pseries/cmm.c | 468 +++++++++++++++++++++++++++=
+++++
3 files changed, 492 insertions(+)
Index: b/arch/powerpc/platforms/pseries/Kconfig
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
From: Robert Jennings <hidden> Date: 2008-07-23 18:31:01
=46rom: Brian King [off-list ref]
With the addition of Cooperative Memory Overcommitment (CMO) support
for IBM Power Systems, two fields have been added to the VPA to report
paging statistics. Add support in lparcfg to report them to userspace.
Signed-off-by: Brian King <redacted>
Signed-off-by: Robert Jennings <redacted>
---
arch/powerpc/kernel/lparcfg.c | 20 ++++++++++++++++++++
include/asm-powerpc/lppaca.h | 5 ++++-
2 files changed, 24 insertions(+), 1 deletion(-)
Index: b/arch/powerpc/kernel/lparcfg.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
@@ -125,7 +125,10 @@ struct lppaca {// NOTE: This value will ALWAYS be zero for dedicated processors and// will NEVER be zero for shared processors (ie, initialized to a 1).volatileu32yield_count;// PLIC increments each dispatchx00-x03-u8reserved6[124];// Reserved x04-x7F+u32reserved6;+volatileu64cmo_faults;// CMO page fault count x08-x0F+volatileu64cmo_fault_time;// CMO page fault time x10-x17+u8reserved7[104];// Reserved x18-x7F
From: Robert Jennings <hidden> Date: 2008-07-23 18:31:29
To support Cooperative Memory Overcommitment (CMO), we need to check
for failure from some of the tce hcalls.
These changes for the pseries platform affect the powerpc architecture;
patches for the other affected platforms are included in this patch.
pSeries platform IOMMU code changes:
* platform TCE functions must handle H_NOT_ENOUGH_RESOURCES errors and
return an error.
Architecture IOMMU code changes:
* Calls to ppc_md.tce_build need to check return values and return
DMA_MAPPING_ERROR for transient errors.
Architecture changes:
* struct machdep_calls for tce_build*_pSeriesLP functions need to change
to indicate failure.
* all other platforms will need updates to iommu functions to match the new
calling semantics; they will return 0 on success. The other platforms
default configs have been built, but no further testing was performed.
Signed-off-by: Robert Jennings <redacted>
Acked-by: Olof Johansson <redacted>
---
Rebased against tree now that it contains Mark Nelson's patch
"powerpc/dma: implement new dma_*map*_attrs() interfaces" to preserve the
'attrs' field in [un]map_sg, [un]map_single functions.
Rebased against tree now that it contains Michael Ellerman's patch "Fix
sparse warnings in arch/powerpc/platforms/pseries" and made a correction
in tce_buildmulti_pSeriesLP for this new code as necessary.
---
arch/powerpc/kernel/iommu.c | 28 ++++++++++++++++++----
arch/powerpc/platforms/cell/iommu.c | 3 +-
arch/powerpc/platforms/iseries/iommu.c | 3 +-
arch/powerpc/platforms/pasemi/iommu.c | 3 +-
arch/powerpc/platforms/pseries/iommu.c | 42 +++++++++++++++++++++++++--------
arch/powerpc/sysdev/dart_iommu.c | 3 +-
include/asm-powerpc/machdep.h | 2 +-
7 files changed, 64 insertions(+), 20 deletions(-)
Index: b/arch/powerpc/kernel/iommu.c
===================================================================
@@ -205,9 +208,21 @@ static dma_addr_t iommu_alloc(struct devret=entry<<IOMMU_PAGE_SHIFT;/* Set the return dma address *//* Put the TCEs in the HW table */-ppc_md.tce_build(tbl,entry,npages,(unsignedlong)page&IOMMU_PAGE_MASK,-direction,attrs);+build_fail=ppc_md.tce_build(tbl,entry,npages,+(unsignedlong)page&IOMMU_PAGE_MASK,+direction,attrs);++/* ppc_md.tce_build() only returns non-zero for transient errors.+*Cleanupthetablebitmapinthiscaseandreturn+*DMA_ERROR_CODE.Forallothererrorsthefunctionalityis+*notaltered.+*/+if(unlikely(build_fail)){+__iommu_free(tbl,ret,npages);+spin_unlock_irqrestore(&(tbl->it_lock),flags);+returnDMA_ERROR_CODE;+}/* Flush/invalidate TLB caches if necessary */if(ppc_md.tce_flush)
@@ -276,7 +291,7 @@ int iommu_map_sg(struct device *dev, strdma_addr_tdma_next=0,dma_addr;unsignedlongflags;structscatterlist*s,*outs,*segstart;-intoutcount,incount,i;+intoutcount,incount,i,build_fail=0;unsignedintalign;unsignedlonghandle;unsignedintmax_seg_size;
@@ -337,8 +352,11 @@ int iommu_map_sg(struct device *dev, strnpages,entry,dma_addr);/* Insert into HW table */-ppc_md.tce_build(tbl,entry,npages,vaddr&IOMMU_PAGE_MASK,-direction,attrs);+build_fail=ppc_md.tce_build(tbl,entry,npages,+vaddr&IOMMU_PAGE_MASK,+direction,attrs);+if(unlikely(build_fail))+gotofailure;/* If we are in an open segment, try merging */if(segstart!=s){
@@ -153,9 +168,8 @@ static void tce_buildmulti_pSeriesLP(strtcep=(u64*)__get_free_page(GFP_ATOMIC);/* If allocation fails, fall back to the loop implementation */if(!tcep){-tce_build_pSeriesLP(tbl,tcenum,npages,uaddr,+returntce_build_pSeriesLP(tbl,tcenum,npages,uaddr,direction,attrs);-return;}__get_cpu_var(tce_page)=tcep;}
From: Robert Jennings <hidden> Date: 2008-07-23 18:31:40
=46rom: Robert Jennings [off-list ref]
This is a large patch but the normal code path is not affected. For
non-pSeries platforms the code is ifdef'ed out and for non-CMO enabled
pSeries systems this does not affect the normal code path. Devices that
do not perform DMA operations do not need modification with this patch.
The function get_desired_dma was renamed from get_io_entitlement for
clarity.
Overview
Cooperative Memory Overcommitment (CMO) allows for a set of OS partitions
to be run with less RAM than the aggregate needs of the group of
partitions. The firmware will balance memory between the partitions
and page in/out memory as needed. Based on the number and type of IO
adpaters preset each partition is allocated an amount of memory for
DMA operations and this allocation will be guaranteed to the partition;
this is referred to as the partition's 'entitlement'.
Partitions running in a CMO environment can only have virtual IO devices
present. The VIO bus layer will manage the IO entitlement for the system.
Accounting, at a system and per-device level, is tracked in the VIO bus
code and exposed via sysfs. A set of dma_ops functions are added to
the bus to allow for this accounting.
Bus initialization
At initialization, the bus will calculate the minimum needs of the system
based on providing each device present with a standard minimum entitlement
along with a spare allocation for the bus to handle hotplug events.
If the minimum needs can not be met the system boot will be halted.
Device changes
The significant changes for devices while running under CMO are that the
devices must specify how much dedicated IO entitlement they desire and
must also handle DMA mapping errors that can occur due to constrained
IO memory. The virtual IO drivers are modified to silence errors when
DMA mappings fail for CMO and handle these failures gracefully.
Each devices will be guaranteed a minimum entitlement that can always
be mapped. Devices will specify how much entitlement they desire and
the VIO bus will attempt to provide for this. Devices can change their
desired entitlement level at any point in time to address particular needs
(via vio_cmo_set_dev_desired()), not just at device probe time.
VIO bus changes
The system will have a particular entitlement level available from which
it can provide memory to the devices. The bus defines two pools of memory
within this entitlement, the reserved and excess pools. Each device is
provided with it's own entitlement no less than a system defined minimum
entitlement and no greater than what the device has specified as it's
desired entitlement. The entitlement provided to devices comes from the
reserve pool. The reserve pool can also contain a spare allocation as
large as the system defined minimum entitlement which is used for device
hotplug events. Any entitlement not needed to fulfill the needs of a
reserve pool is placed in the excess pool. Each device is guaranteed
that it can map up to it's entitled level; additional mapping are possible
as long as there is unmapped memory in the excess pool.
Bus probe
As the system starts, each device is given an entitlement equal only
to the system defined minimum entitlement. The reserve pool is equal
to the sum of these entitlements, plus a spare allocation. The VIO bus
also tracks the aggregate desired entitlement of all the devices. If the
system desired entitlement is greater than the size of the reserve pool,
when devices unmap IO memory it will be reserved and a balance operation
will be scheduled for some time in the future.
Entitlement balancing
The balance function tries to fairly distribute entitlement between the
devices in the system with the goal of providing each device with it's
desired amount of entitlement. Devices using more than what would be
ideal will have their entitled set-point adjusted; this will effectively
set a goal for lower IO memory usage as future mappings can fail and
deallocations will trigger a balance operation to distribute the newly
unmapped memory. A fair distribution of entitlement can take several
balance operations to achieve. Entitlement changes and device DLPAR
events will alter the state of CMO and will trigger balance operations.
Hotplug events
The VIO bus allows for changes in system entitlement at run-time via
'vio_cmo_entitlement_update()'. When devices are added the hotplug
device event will be preceded by a system entitlement increase and this
is reversed when devices are removed.
The following changes are made that the VIO bus layer for CMO:
* add IO memory accounting per device structure.
* add IO memory entitlement query function to driver structure.
* during vio bus probe, if CMO is enabled, check that driver has
memory entitlement query function defined. Fail if function not defined.
* fail to register driver if io entitlement function not defined.
* create set of dma_ops at vio level for CMO that will track allocations
and return DMA failures once entitlement is reached. Entitlement will
limited by overall system entitlement. Devices will have a reserved
quantity of memory that is guaranteed, the rest can be used as available.
* expose entitlement, current allocation, desired allocation, and the
allocation error counter for devices to the user through sysfs
* provide mechanism for changing a device's desired entitlement at run time
for devices as an exported function and sysfs tunable
* track any DMA failures for entitled IO memory for each vio device.
* check entitlement against available system entitlement on device add
* track entitlement metrics (high water mark, current usage)
* provide function to reset high water mark
* provide minimum and desired entitlement numbers at a bus level
* provide drivers with a minimum guaranteed entitlement
* balance available entitlement between devices to satisfy their needs
* handle system entitlement changes and device hotplug
Signed-off-by: Robert Jennings <redacted>
---
Change to add a call to align the return from the device's
get_desired_dma() function with IOMMU_PAGE_ALIGN(). Changed accounting
to round to IOMMU_PAGE_SIZE rather than PAGE_SIZE to properly count
mapping when using a 64k page kernel with 4k page hardware support.
Removed a comment referring to a non-existent structure member.
Corrected entitlement accounting in map_sg. The ibmvscsi driver
maps pages via map_sg and frees the sg list by calling unmap_single.
This exposes a problem where the code had been using the length field
in the scatterlist to account for the allocation when the mapping was
created but the dma_length would be used when the mapping was destroyed.
The iommu code does coalesce the pages so the dma_length can be smaller
and would result in an entitlement accounting leak. This patch frees
up the entitlement after calling the iommu map_sg code when pages have
been coalesced.
Added Kconfig entry for this with dependencies that will ensure h_get_mpp
=66rom lparcfg is available when the new functionality is compiled.
---
arch/powerpc/kernel/vio.c | 1033 ++++++++++++++++++++++++++++=
+++++
arch/powerpc/platforms/pseries/Kconfig | 13 +
include/asm-powerpc/vio.h | 27 +
3 files changed, 1064 insertions(+), 9 deletions(-)
Index: b/arch/powerpc/kernel/vio.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
=20
id =3D vio_match_device(viodrv->id_table, viodev);
- if (id)
+ if (id) {
+ memset(&viodev->cmo, 0, sizeof(viodev->cmo));
+ if (firmware_has_feature(FW_FEATURE_CMO)) {
+ error =3D vio_cmo_bus_probe(viodev);
+ if (error)
+ return error;
+ }
error =3D viodrv->probe(viodev, id);
+ if (error)
+ vio_cmo_bus_remove(viodev);
+ }
=20
return error;
}
@@ -125,12 +1125,23 @@ static int vio_bus_remove(struct device=20 { struct vio_dev *viodev =3D to_vio_dev(dev); struct vio_driver *viodrv =3D to_vio_driver(dev->driver);+ struct device *devptr;+ int ret =3D 1;++ /*+ * Hold a reference to the device after the remove function is called+ * to allow for CMO accounting cleanup for the device.+ */+ devptr =3D get_device(dev);
=20
+/*
+ * VIO CMO minimum entitlement for all devices and spare entitlement
+ */
+#define VIO_CMO_MIN_ENT 1562624
+
struct iommu_table;
=20
-/*
- * The vio_dev structure is used to describe virtual I/O devices.
+/**
+ * vio_dev - This structure is used to describe virtual I/O devices.
+ *
+ * @desired: set from return of driver's get_desired_dma() function
+ * @entitled: bytes of IO data that has been reserved for this device.
+ * @allocated: bytes of IO data currently in use by the device.
+ * @allocs_failed: number of DMA failures due to insufficient entitlement.
*/
struct vio_dev {
const char *name;
const char *type;
uint32_t unit_address;
unsigned int irq;
+ struct {
+ size_t desired;
+ size_t entitled;
+ size_t allocated;
+ atomic_t allocs_failed;
+ } cmo;
struct device dev;
};
=20
@@ -56,12 +72,19 @@ struct vio_driver { const struct vio_device_id *id_table; int (*probe)(struct vio_dev *dev, const struct vio_device_id *id); int (*remove)(struct vio_dev *dev);+ /* A driver must have a get_desired_dma() function to+ * be loaded in a CMO environment if it uses DMA.+ */+ unsigned long (*get_desired_dma)(struct vio_dev *dev); struct device_driver driver; };
=20
+ if (entitlement) {
+ /* Check with vio to ensure the new memory entitlement
+ * can be handled.
+ */
+ rc =3D vio_cmo_entitlement_update(*entitlement);
+ if (rc)
+ return rc;
+ }
+
rc =3D h_get_mpp(&mpp_data);
if (rc)
return rc;
From: Robert Jennings <hidden> Date: 2008-07-23 18:34:28
=46rom: Santiago Leon [off-list ref]
Activates larger rx buffer pools when the MTU is changed to a larger
value. This patch de-activates the large rx buffer pools when the MTU
changes to a smaller value.
Signed-off-by: Santiago Leon <redacted>
Signed-off-by: Robert Jennings <redacted>
---
We would like to take this patch through linuxppc-dev with the full
change set for this feature. We are copying netdev for review and ack.
---
drivers/net/ibmveth.c | 20 +++++++++++++-------
1 file changed, 13 insertions(+), 7 deletions(-)
Index: b/drivers/net/ibmveth.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
@@ -1054,7 +1054,6 @@ static int ibmveth_change_mtu(struct net{structibmveth_adapter*adapter=3Ddev->priv;intnew_mtu_oh=3Dnew_mtu+IBMVETH_BUFF_OH;-intreinit=3D0;inti,rc;
=20
if (new_mtu < IBMVETH_MAX_MTU)
@@ -1067,15 +1066,21 @@ static int ibmveth_change_mtu(struct net if (i =3D=3D IbmVethNumBufferPools) return -EINVAL;
=20
+ /* Deactivate all the buffer pools so that the next loop can activate
+ only the buffer pools necessary to hold the new MTU */
+ for (i =3D 0; i < IbmVethNumBufferPools; i++)
+ if (adapter->rx_buff_pool[i].active) {
+ ibmveth_free_buffer_pool(adapter,
+ &adapter->rx_buff_pool[i]);
+ adapter->rx_buff_pool[i].active =3D 0;
+ }
+
/* Look for an active buffer pool that can hold the new MTU */
for(i =3D 0; i<IbmVethNumBufferPools; i++) {
- if (!adapter->rx_buff_pool[i].active) {
- adapter->rx_buff_pool[i].active =3D 1;
- reinit =3D 1;
- }
+ adapter->rx_buff_pool[i].active =3D 1;
=20
if (new_mtu_oh < adapter->rx_buff_pool[i].buff_size) {
- if (reinit && netif_running(adapter->netdev)) {
+ if (netif_running(adapter->netdev)) {
adapter->pool_config =3D 1;
ibmveth_close(adapter->netdev);
adapter->pool_config =3D 0;
From: Robert Jennings <hidden> Date: 2008-07-23 18:34:56
Enable ibmveth for Cooperative Memory Overcommitment (CMO). For this driver
it means calculating a desired amount of IO memory based on the current MTU
and updating this value with the bus when MTU changes occur. Because DMA
mappings can fail, we have added a bounce buffer for temporary cases where
the driver can not map IO memory for the buffer pool.
The following changes are made to enable the driver for CMO:
* DMA mapping errors will not result in error messages if entitlement has
been exceeded and resources were not available.
* DMA mapping errors are handled gracefully, ibmveth_replenish_buffer_pool()
is corrected to check the return from dma_map_single and fail gracefully.
* The driver will have a get_desired_dma function defined to function
in a CMO environment.
* When the MTU is changed, the driver will update the device IO entitlement
Signed-off-by: Robert Jennings <redacted>
Signed-off-by: Brian King <redacted>
Signed-off-by: Santiago Leon <redacted>
---
We would like to take this patch through linuxppc-dev with the full
change set for this feature. We are copying netdev for review and ack.
---
drivers/net/ibmveth.c | 169 ++++++++++++++++++++++++++++++++++++++++----------
drivers/net/ibmveth.h | 5 +
2 files changed, 140 insertions(+), 34 deletions(-)
Index: b/drivers/net/ibmveth.c
===================================================================
@@ -607,6 +634,24 @@ static int ibmveth_open(struct net_devicreturnrc;}+adapter->bounce_buffer=+kmalloc(netdev->mtu+IBMVETH_BUFF_OH,GFP_KERNEL);+if(!adapter->bounce_buffer){+ibmveth_error_printk("unable to allocate bounce buffer\n");+ibmveth_cleanup(adapter);+napi_disable(&adapter->napi);+return-ENOMEM;+}+adapter->bounce_buffer_dma=+dma_map_single(&adapter->vdev->dev,adapter->bounce_buffer,+netdev->mtu+IBMVETH_BUFF_OH,DMA_BIDIRECTIONAL);+if(dma_mapping_error(adapter->bounce_buffer_dma)){+ibmveth_error_printk("unable to map bounce buffer\n");+ibmveth_cleanup(adapter);+napi_disable(&adapter->napi);+return-ENOMEM;+}+ibmveth_debug_printk("initial replenish cycle\n");ibmveth_interrupt(netdev->irq,netdev);
@@ -853,10 +898,12 @@ static int ibmveth_start_xmit(struct sk_unsignedinttx_packets=0;unsignedinttx_send_failed=0;unsignedinttx_map_failed=0;+intused_bounce=0;+unsignedlongdata_dma_addr;desc.fields.flags_len=IBMVETH_BUF_VALID|skb->len;-desc.fields.address=dma_map_single(&adapter->vdev->dev,skb->data,-skb->len,DMA_TO_DEVICE);+data_dma_addr=dma_map_single(&adapter->vdev->dev,skb->data,+skb->len,DMA_TO_DEVICE);if(skb->ip_summed==CHECKSUM_PARTIAL&&ip_hdr(skb)->protocol!=IPPROTO_TCP&&skb_checksum_help(skb)){
@@ -875,12 +922,16 @@ static int ibmveth_start_xmit(struct sk_buf[1]=0;}-if(dma_mapping_error(desc.fields.address)){-ibmveth_error_printk("tx: unable to map xmit buffer\n");+if(dma_mapping_error(data_dma_addr)){+if(!firmware_has_feature(FW_FEATURE_CMO))+ibmveth_error_printk("tx: unable to map xmit buffer\n");+skb_copy_from_linear_data(skb,adapter->bounce_buffer,+skb->len);+desc.fields.address=adapter->bounce_buffer_dma;tx_map_failed++;-tx_dropped++;-gotoout;-}+used_bounce=1;+}else+desc.fields.address=data_dma_addr;/* send the frame. Arbitrarily set retrycount to 1024 */correlator=0;
@@ -904,8 +955,9 @@ static int ibmveth_start_xmit(struct sk_netdev->trans_start=jiffies;}-dma_unmap_single(&adapter->vdev->dev,desc.fields.address,-skb->len,DMA_TO_DEVICE);+if(!used_bounce)+dma_unmap_single(&adapter->vdev->dev,data_dma_addr,+skb->len,DMA_TO_DEVICE);out:spin_lock_irqsave(&adapter->stats_lock,flags);netdev->stats.tx_dropped+=tx_dropped;
@@ -1085,10 +1138,15 @@ static int ibmveth_change_mtu(struct netibmveth_close(adapter->netdev);adapter->pool_config=0;dev->mtu=new_mtu;-if((rc=ibmveth_open(adapter->netdev)))-returnrc;-}else-dev->mtu=new_mtu;+vio_cmo_set_dev_desired(viodev,+ibmveth_get_desired_dma+(viodev));+returnibmveth_open(adapter->netdev);+}+dev->mtu=new_mtu;+vio_cmo_set_dev_desired(viodev,+ibmveth_get_desired_dma+(viodev));return0;}}
@@ -1103,6 +1161,46 @@ static void ibmveth_poll_controller(stru}#endif+/**+*ibmveth_get_desired_dma-CalculateIOmemorydesiredbythedriver+*+*@vdev:structvio_devforthedevicewhosedesiredIOmemistobereturned+*+*Returnvalue:+*NumberofbytesofIOdatathedriverwillneedtoperformwell.+*/+staticunsignedlongibmveth_get_desired_dma(structvio_dev*vdev)+{+structnet_device*netdev=dev_get_drvdata(&vdev->dev);+structibmveth_adapter*adapter;+unsignedlongret;+inti;+intrxqentries=1;++/* netdev inits at probe time along with the structures we need below*/+if(netdev==NULL)+returnIOMMU_PAGE_ALIGN(IBMVETH_IO_ENTITLEMENT_DEFAULT);++adapter=netdev_priv(netdev);++ret=IBMVETH_BUFF_LIST_SIZE+IBMVETH_FILT_LIST_SIZE;+ret+=IOMMU_PAGE_ALIGN(netdev->mtu);++for(i=0;i<IbmVethNumBufferPools;i++){+/* add the size of the active receive buffers */+if(adapter->rx_buff_pool[i].active)+ret+=+adapter->rx_buff_pool[i].size*+IOMMU_PAGE_ALIGN(adapter->rx_buff_pool[i].+buff_size);+rxqentries+=adapter->rx_buff_pool[i].size;+}+/* add the size of the receive queue entries */+ret+=IOMMU_PAGE_ALIGN(rxqentries*sizeof(structibmveth_rx_q_entry));++returnret;+}+staticint__devinitibmveth_probe(structvio_dev*dev,conststructvio_device_id*id){intrc,i;
@@ -1247,6 +1345,8 @@ static int __devexit ibmveth_remove(struibmveth_proc_unregister_adapter(adapter);free_netdev(netdev);+dev_set_drvdata(&dev->dev,NULL);+return0;}
From: Robert Jennings <hidden> Date: 2008-07-23 18:35:32
=46rom: Robert Jennings [off-list ref]
Enable the driver to function in a Cooperative Memory Overcommitment (CMO)
environment.
The following changes are made to enable the driver for CMO:
* DMA mapping errors will not result in error messages if entitlement has
been exceeded and resources were not available.
* The driver has a get_desired_dma function defined to function
in a CMO environment. It will indicate how much IO memory it would like
to function.
Signed-off-by: Robert Jennings <redacted>
Acked by: Brian King [off-list ref]
---
We would like to take this patch through linuxppc-dev with the full
change set for this feature. We are copying linux-scsi for review and ack.
---
drivers/scsi/ibmvscsi/ibmvscsi.c | 45 +++++++++++++++++++++++++++++++++-=
-----
drivers/scsi/ibmvscsi/ibmvscsi.h | 2 ++
2 files changed, 40 insertions(+), 7 deletions(-)
Index: b/drivers/scsi/ibmvscsi/ibmvscsi.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
=20
/**
+ * ibmvscsi_get_desired_dma - Calculate IO memory desired by the driver
+ *
+ * @vdev: struct vio_dev for the device whose desired IO mem is to be retu=
rned
+ *
+ * Return value:
+ * Number of bytes of IO data the driver will need to perform well.
+ */
+static unsigned long ibmvscsi_get_desired_dma(struct vio_dev *vdev)
+{
+ /* iu_storage data allocated in initialize_event_pool */
+ unsigned long desired_io =3D max_requests * sizeof(union viosrp_iu);
+
+ /* add io space for sg data */
+ desired_io +=3D (IBMVSCSI_MAX_SECTORS_DEFAULT *
+ IBMVSCSI_CMDS_PER_LUN_DEFAULT);
+
+ return desired_io;
+}
+
+/**
* Called by bus code for each adapter
*/
static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id=
*id)
From: Benjamin Herrenschmidt <benh@kernel.crashing.org> Date: 2008-07-24 05:59:42
On Wed, 2008-07-23 at 13:35 -0500, Robert Jennings wrote:
From: Robert Jennings <redacted>
Enable the driver to function in a Cooperative Memory Overcommitment (CMO)
environment.
The following changes are made to enable the driver for CMO:
* DMA mapping errors will not result in error messages if entitlement has
been exceeded and resources were not available.
* The driver has a get_desired_dma function defined to function
in a CMO environment. It will indicate how much IO memory it would like
to function.
Signed-off-by: Robert Jennings <redacted>
Acked by: Brian King [off-list ref]
---
We would like to take this patch through linuxppc-dev with the full
change set for this feature. We are copying linux-scsi for review and ack.
James, if you are ok with this patch, can you Ack it ? I'll merge it via
the powerpc tree along with all its dependencies.
Thanks in advance !
Cheers,
Ben.
@@ -426,8 +427,10 @@ static int map_sg_data(struct scsi_cmnd SG_ALL*sizeof(structsrp_direct_buf),&evt_struct->ext_list_token,0);if(!evt_struct->ext_list){-sdev_printk(KERN_ERR,cmd->device,-"Can't allocate memory for indirect table\n");+if(!firmware_has_feature(FW_FEATURE_CMO))+sdev_printk(KERN_ERR,cmd->device,+"Can't allocate memory "+"for indirect table\n");return0;}}
@@ -743,7 +746,9 @@ static int ibmvscsi_queuecommand(struct srp_cmd->lun=((u64)lun)<<48;if(!map_data_for_srp_cmd(cmnd,evt_struct,srp_cmd,hostdata->dev)){-sdev_printk(KERN_ERR,cmnd->device,"couldn't convert cmd to srp_cmd\n");+if(!firmware_has_feature(FW_FEATURE_CMO))+sdev_printk(KERN_ERR,cmnd->device,+"couldn't convert cmd to srp_cmd\n");free_event_struct(&hostdata->pool,evt_struct);returnSCSI_MLQUEUE_HOST_BUSY;}
@@ -855,7 +860,10 @@ static void send_mad_adapter_info(structDMA_BIDIRECTIONAL);if(dma_mapping_error(req->buffer)){-dev_err(hostdata->dev,"Unable to map request_buffer for adapter_info!\n");+if(!firmware_has_feature(FW_FEATURE_CMO))+dev_err(hostdata->dev,+"Unable to map request_buffer for "+"adapter_info!\n");free_event_struct(&hostdata->pool,evt_struct);return;}
@@ -1613,6 +1623,26 @@ static struct scsi_host_template driver_};/**+*ibmvscsi_get_desired_dma-CalculateIOmemorydesiredbythedriver+*+*@vdev:structvio_devforthedevicewhosedesiredIOmemistobereturned+*+*Returnvalue:+*NumberofbytesofIOdatathedriverwillneedtoperformwell.+*/+staticunsignedlongibmvscsi_get_desired_dma(structvio_dev*vdev)+{+/* iu_storage data allocated in initialize_event_pool */+unsignedlongdesired_io=max_requests*sizeof(unionviosrp_iu);++/* add io space for sg data */+desired_io+=(IBMVSCSI_MAX_SECTORS_DEFAULT*+IBMVSCSI_CMDS_PER_LUN_DEFAULT);++returndesired_io;+}++/***Calledbybuscodeforeachadapter*/staticintibmvscsi_probe(structvio_dev*vdev,conststructvio_device_id*id)
@@ -1641,7 +1671,7 @@ static int ibmvscsi_probe(struct vio_devhostdata->host=host;hostdata->dev=dev;atomic_set(&hostdata->request_limit,-1);-hostdata->host->max_sectors=32*8;/* default max I/O 32 pages */+hostdata->host->max_sectors=IBMVSCSI_MAX_SECTORS_DEFAULT;rc=ibmvscsi_ops->init_crq_queue(&hostdata->queue,hostdata,max_requests);if(rc!=0&&rc!=H_RESOURCE){
From: Robert Jennings <hidden> Date: 2008-07-23 18:35:59
=46rom: Brian King [off-list ref]
Adds support to the ibmvfc driver for collaborative memory overcommit.
Signed-off-by: Brian King <redacted>
Signed-off-by: Robert Jennings <redacted>
---
We would like to take this patch through linuxppc-dev with the full
change set for this feature. We are copying linux-scsi for review and ack.
---
drivers/scsi/ibmvscsi/ibmvfc.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
Index: b/drivers/scsi/ibmvscsi/ibmvfc.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
From: Robert Jennings <hidden> Date: 2008-07-23 18:36:58
=46rom: Nathan Fontenot [off-list ref]
Update the architecture vector to indicate that Cooperative Memory
Overcommitment is supported if CONFIG_PPC_SMLPAR is set.
Signed-off-by: Nathan Fontenot <redacted>
Signed-off-by: Robert Jennings <redacted>
---
This is the last patch in the series. Committing it will signal to=20
the platform firmware is CMO enabled.
Made this dependent on CONFIG_PPC_SMLPAR so that we don't advertise
functionality when the kernel isn't supporting it.
---
arch/powerpc/kernel/prom_init.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
Index: b/arch/powerpc/kernel/prom_init.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D