All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2] pull: Document the "--[no-]recurse-submodules" options
From: Jens Lehmann @ 2011-02-07 19:27 UTC (permalink / raw)
  To: Jonathan Nieder; +Cc: Junio C Hamano, Johannes Sixt, Git Mailing List
In-Reply-To: <20110207074157.GA2736@elie>

In commits be254a0ea9 and 7dce19d374 the handling of the new fetch options
"--[no-]recurse-submodules" had been added to git-pull.sh. But they were
not documented as the pull options they now are, so let's fix that.

Signed-off-by: Jens Lehmann <Jens.Lehmann@web.de>
---

Am 07.02.2011 08:41, schrieb Jonathan Nieder:
> Jens Lehmann wrote:
>> --- a/Documentation/git-pull.txt
>> +++ b/Documentation/git-pull.txt
>> @@ -84,6 +84,10 @@ must be given before the options meant for 'git fetch'.
>>  --verbose::
>>  	Pass --verbose to git-fetch and git-merge.
>>
>> +--[no-]recurse-submodules::
>> +	This option controls if new commits of all populated submodules should
>> +	be fetched too (see linkgit:git-config[1] and linkgit:gitmodules[5]).
>> +
> 
> Is it worth mentioning that this does not (yet) automatically check
> out the new commits in submodules after a merge, or would such
> documentation be too likely to be forgotten and left stale in the
> future?

Good point, here is v2! (And I will add an updated description to the
relevant commits in my github repo, so we won't forget that later)

 Documentation/fetch-options.txt |    2 +-
 Documentation/git-pull.txt      |    9 +++++++++
 2 files changed, 10 insertions(+), 1 deletions(-)

diff --git a/Documentation/fetch-options.txt b/Documentation/fetch-options.txt
index 695696d..ab0dbfc 100644
--- a/Documentation/fetch-options.txt
+++ b/Documentation/fetch-options.txt
@@ -64,11 +64,11 @@ ifndef::git-pull[]
 	downloaded. The default behavior for a remote may be
 	specified with the remote.<name>.tagopt setting. See
 	linkgit:git-config[1].
-endif::git-pull[]

 --[no-]recurse-submodules::
 	This option controls if new commits of all populated submodules should
 	be fetched too (see linkgit:git-config[1] and linkgit:gitmodules[5]).
+endif::git-pull[]

 ifndef::git-pull[]
 --submodule-prefix=<path>::
diff --git a/Documentation/git-pull.txt b/Documentation/git-pull.txt
index 3046691..b33e6be 100644
--- a/Documentation/git-pull.txt
+++ b/Documentation/git-pull.txt
@@ -84,6 +84,15 @@ must be given before the options meant for 'git fetch'.
 --verbose::
 	Pass --verbose to git-fetch and git-merge.

+--[no-]recurse-submodules::
+	This option controls if new commits of all populated submodules should
+	be fetched too (see linkgit:git-config[1] and linkgit:gitmodules[5]).
+	That might be necessary to get the data needed for merging submodule
+	commits, a feature git learned in 1.7.3. Notice that the result of a
+	merge will not be checked out in the submodule, "git submodule update"
+	has to be called afterwards to bring the work tree up to date with the
+	merge result.
+
 Options related to merging
 ~~~~~~~~~~~~~~~~~~~~~~~~~~

-- 
1.7.4.47.g87a200

^ permalink raw reply related

* Re: [PATCH 4/4] watchdog: s3c2410: Add support for device tree based probe
From: Rob Herring @ 2011-02-07 19:27 UTC (permalink / raw)
  To: Thomas Abraham
  Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	kgene.kim-Sze3O3UU22JBDgjK7y7TUQ,
	linaro-dev-cunTk1MwBs8s++Sfvej+rw, patches-QSEj5FYQhm4dnm+yROfE0A
In-Reply-To: <1296998250-21856-5-git-send-email-thomas.abraham-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>

Thomas,

On 02/06/2011 07:17 AM, Thomas Abraham wrote:
> This patch adds the of_match_table to enable s3c2410-wdt driver
> to be probed when watchdog device node is found in the device tree.
>
> Signed-off-by: Thomas Abraham<thomas.abraham-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> ---
>   drivers/watchdog/s3c2410_wdt.c |   10 ++++++++++
>   1 files changed, 10 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c
> index ae53662..a9edd50 100644
> --- a/drivers/watchdog/s3c2410_wdt.c
> +++ b/drivers/watchdog/s3c2410_wdt.c
> @@ -592,6 +592,13 @@ static int s3c2410wdt_resume(struct platform_device *dev)
>   #define s3c2410wdt_resume  NULL
>   #endif /* CONFIG_PM */
>
> +#ifdef CONFIG_OF
> +static const struct of_device_id s3c2410_wdt_match[] = {
> +	{ .compatible = "samsung,s3c2410-wdt" },
> +	{},
> +};
> +MODULE_DEVICE_TABLE(of, s3c2410_wdt_match);
> +#endif
>
>   static struct platform_driver s3c2410wdt_driver = {
>   	.probe		= s3c2410wdt_probe,
> @@ -602,6 +609,9 @@ static struct platform_driver s3c2410wdt_driver = {
>   	.driver		= {
>   		.owner	= THIS_MODULE,
>   		.name	= "s3c2410-wdt",
> +#ifdef CONFIG_OF
> +		.of_match_table	= s3c2410_wdt_match,
> +#endif

The ifdefs aren't necessary if you pick-up Grant's patch in 
devicetree/next branch.

Rob

^ permalink raw reply

* Re: [PATCH 1/5 v3] Cell-info: CellInfo DBUS interface definition
From: Marcel Holtmann @ 2011-02-07 19:27 UTC (permalink / raw)
  To: ofono
In-Reply-To: <1294833919-1510-2-git-send-email-antti.paila@nokia.com>

[-- Attachment #1: Type: text/plain, Size: 1306 bytes --]

Hi Antti,

>  include/dbus.h |    1 +
>  src/ofono.h    |    1 +
>  2 files changed, 2 insertions(+), 0 deletions(-)
> 
> diff --git a/include/dbus.h b/include/dbus.h
> index 12768f6..f2e18bf 100644
> --- a/include/dbus.h
> +++ b/include/dbus.h
> @@ -45,6 +45,7 @@ extern "C" {
>  #define OFONO_MESSAGE_WAITING_INTERFACE "org.ofono.MessageWaiting"
>  #define OFONO_NETWORK_REGISTRATION_INTERFACE "org.ofono.NetworkRegistration"
>  #define OFONO_NETWORK_OPERATOR_INTERFACE "org.ofono.NetworkOperator"
> +#define OFONO_CELL_INFO_INTERFACE "org.ofono.CellInfo"
>  #define OFONO_PHONEBOOK_INTERFACE "org.ofono.Phonebook"
>  #define OFONO_RADIO_SETTINGS_INTERFACE "org.ofono.RadioSettings"
>  #define OFONO_AUDIO_SETTINGS_INTERFACE "org.ofono.AudioSettings"
> diff --git a/src/ofono.h b/src/ofono.h
> index cab70cd..820e3a3 100644
> --- a/src/ofono.h
> +++ b/src/ofono.h
> @@ -127,6 +127,7 @@ enum ofono_atom_type {
>  	OFONO_ATOM_TYPE_NETTIME = 21,
>  	OFONO_ATOM_TYPE_CTM = 22,
>  	OFONO_ATOM_TYPE_CDMA_VOICECALL_MANAGER = 23,
> +	OFONO_ATOM_TYPE_CELL_INFO = 24,
>  };

This is a little bit confusing since the atom enum doesn't really have
to do anything with the D-Bus interface name. You might wanna feed that
into some other patch or split it out.

Regards

Marcel



^ permalink raw reply

* Re: Early crash
From: David Miller @ 2011-02-07 19:27 UTC (permalink / raw)
  To: dtor; +Cc: schwab, geert, rusty, linux-kernel, linux-m68k, linux-arch
In-Reply-To: <20110207165829.GA13101@dtor-ws.eng.vmware.com>

From: Dmitry Torokhov <dtor@vmware.com>
Date: Mon, 7 Feb 2011 08:58:29 -0800

> But, theoretically speaking, nothing stops GCC to align pointers with
> "gaps" as well? Let's say having everything (or some) aligned on
> quadword boundary even though arch is 32 bit?

The alignment business only applies to aggregates (ie. structs and
unions).

This has been confirmed via several weeks of expermentation with
different GCC versions on different platforms as well.

^ permalink raw reply

* Re: [1.8.0] Provide proper remote ref namespaces
From: Bernhard R. Link @ 2011-02-07 19:05 UTC (permalink / raw)
  To: Dmitry Potapov
  Cc: git, Junio C Hamano, Sverre Rabbelier, Jeff King,
	Nguyen Thai Ngoc Duy, Nicolas Pitre, Johan Herland
In-Reply-To: <AANLkTi=A-rh+wfg7O4KryydxVuorM8nkuGYmpbgVfVJp@mail.gmail.com>

* Dmitry Potapov <dpotapov@gmail.com> [110207 01:07]:
> There are two sorts of tags:
> - local tags, which are never intended to be shared with others but used
>   by users to mark some points in the working repository.
> - global tags, which are just _social_convention_ about what the current
>   project considers as official versions. Without social convention, they
>   make no sense.
>[...]
> It seems you do not understand the problem that I am trying to say all
> way along: there is more than one repo from which I fetch tags, and
> because they are belong to the same project, they should be in the same
> namespace.

So there are those "local tags", which are not to be shared with others.
Does that mean an user should always have two repositories, one with
those tags for themselves and one without those tags for each other?

And the private one should always be the one that does the push and
fetch (as issuing a a fetch in the public to get something from the
private will also get all those tags)?

> > Granted, if we leave all tags in a single namespace, I can still work around
> > this by manually futzing with the configured refspecs to create ad hoc
> > namespaces. But I _really_ hate it when I'm forced to hack around the tool,
> > because the tool thinks it "knows better".
>
> I believe that the right interface when the common case is simple, but
> an uncommon case is still possible to handle. I don't think that
> currently git meets this criterion, but making tag namespaces based on
> the remote name strikes me as a really bad idea. Tags are attributes of
> a project and not particular remote.

Global tags are. Local tags are not.
And even for global tags it can be interesting to see which remote has
them, without having to manually look at all those remotes.

> IMHO, it is very confusing, especially for people whose script was
> suddenly broken by those namespaces.

Like it was when remotes where introduced?

> So, IMHO, the proper solution should be ability to specify the desired
> namespace for any remote repository, like this:
>
> remote.<name>.tagNameSpace = foo
>
> So, those who want to have many namespaces should be able to that
> easily, but forcing multiple namespaces on those who have a single
> namespace semantically is simple wrong. Not to mention that it breaks
> existing scripts for no good reason.

I'd consider it more logical to have remote tags and a config to
automatically make local copies of remote tags. (With whatever default
people consider proper).


	Bernhard R. Link

^ permalink raw reply

* Re: Local copy of the repository files
From: Conrad Irwin @ 2011-02-07 19:22 UTC (permalink / raw)
  To: Roberto; +Cc: git
In-Reply-To: <4D503E0D.5050105@gmail.com>

On 7 February 2011 10:46, Roberto <mrgreiner@gmail.com> wrote:
> Hi,
>
> I'm trying to make my git repository automatically make a local copy o f the
> repository files, but the appropriate command (or commands) is eluding me.
> Could somebody give me a hint (or point to the appropriate document) as of
> how to make it work?

There's a reasonably succinct guide to setting this up at
http://toroid.org/ams/git-website-howto

Conrad

^ permalink raw reply

* Re: [PATCH 5/5 v3] Cell-info: Documentation
From: Marcel Holtmann @ 2011-02-07 19:24 UTC (permalink / raw)
  To: ofono
In-Reply-To: <1294833919-1510-6-git-send-email-antti.paila@nokia.com>

[-- Attachment #1: Type: text/plain, Size: 4708 bytes --]

Hi Antti,

>  doc/cell-info.txt |  121 +++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 121 insertions(+), 0 deletions(-)
>  create mode 100644 doc/cell-info.txt
> 
> diff --git a/doc/cell-info.txt b/doc/cell-info.txt
> new file mode 100644
> index 0000000..64d9db6
> --- /dev/null
> +++ b/doc/cell-info.txt
> @@ -0,0 +1,121 @@
> +Cell Info hierarchy
> +===================
> +
> +Service		org.ofono
> +Interface	org.ofono.CellInfo
> +Object path	[variable prefix]/{modem0,modem1,...}
> +
> +Methods 	aa{sv} GetNeighbors()
> +
> +			Calling this procedure returns properties of serving
> +			and neighboring cells in GSM or WCDMA networks. This
> +			information can be used to determine current location
> +			using triangulation over neighboring cell tower
> +			locations and estimated distances.
> +
> +			The returned array consists of two parts: 1) first
> +			element of the array contains a dictionary of
> +			common information about network and serving cell 2)
> +			rest of the array comprises dictionaries containing
> +			measurement results of neighboring cells. The contents
> +			of the dictionaries follow the specification
> +			OMA-TS-ULP-V2_0-20100816-C for user plane Location and
> +			is described in properties section.

I am having a little bit of a problem calling this GetNeighbors and then
also retrieving the serving cell at the same time.

I am just spinning some idea here, but maybe calling the interface
org.ofono.NeighborCellInfo and the method AquireMeasurment() would be
better.

> +			Possible errors: org.ofono.Error.Failed
> +
> +Properties
> +
> +Serving cell
> +		string Type
> +			Radio access network type of neighbor cell information.
> +			The possible values are:
> +			"geran"	Measurement results are for the GSM EDGE Radio
> +				Access Network.
> +			"utran"	Measurement results are for UMTS Radio Access
> +				Network.
> +
> +		string MobileCountryCode
> +			Mobile Country Code of serving cell. Possible values:
> +			Values: 0...999
> +
> +		string MobileNetworkCode
> +			Mobile Network Code of serving cell.
> +			Values: 0...999
> +
> +		uint16 LocationAreaCode [GERAN]
> +			Location area code of serving cell.
> +			Values: 0...65535
> +
> +		uint16 CellId [GERAN]
> +			Cell Id of serving cell.
> +			Values: 0...65535
> +
> +		byte TimingAdvance [GERAN, optional]
> +			Timing advance.
> +			Values: 0...63
> +
> +		uint32 UniqueCellId [UTRA-FDD]
> +			Serving WCDMA unique cell ID.
> +			Values: 0...268435455
> +
> +		uint16 ScramblingCode [UTRA-FDD]
> +			Primary scrambling code.
> +			Values: 0...511
> +
> +		uint16 UARFCN-DL [UTRA-FDD]
> +			Downlink UTRA Absolute Radio Frequency Channel Number
> +			of serving cell.
> +			Values: 0...16383

Do we wanna keep the UARFCN acronym?

> +		uint16 UARFCN-UL [UTRA-FDD, optional]
> +			Uplink UTRA Absolute Radio Frequency Channel Number.
> +			Values: 0...16383

I am still going forth and back if it is a good idea to make cell[0]
special as the serving cell. There are common fields, but also other
fields that are totally different.

So one question that came to my mind is how this mixes when the serving
cell is UMTS, can the neighbors cells also report GSM? Do we have a mix
of values in the dictionary anyway?

> +Neighbor cell measurement results
> +
> +		uint16 AbsoluteRadioFrequencyChannelNumber [GERAN]
> +			Absolute radio frequency channel number.
> +			Values: 0...1023
> +
> +		byte BaseStationIdentityCode [GERAN]
> +			Base station identity code.
> +			Values: 0...63.
> +
> +		byte RXLEV [GERAN]
> +			Measured power of the channel.
> +			Values: 0...63

I think we can find something better name than RXLEV.

> +		byte ReceivedSignalStrengthIndicator [UTRA-FDD]
> +			RX power level.
> +			Values: 0...127
> +
> +		uint16 UARFCN-DL [UTRA-FDD]
> +			Downlink UARFCN.
> +			Values: 0...16383
> +
> +		uint16 UARFCN-UL [UTRA-FDD, optional]
> +			Uplink UARFCN.
> +			Values: 0...16383
> +
> +		uint16 ScramblingCode [UTRA-FDD]
> +			Primary scrambling code.
> +			Values: 0...511
> +
> +		uint32 UniqueCellId [UTRA-FDD, optional]
> +			Unique cell ID.
> +			Values: 0...268435455
> +
> +		byte CPICH-ECN0 [UTRA-FDD, optional]
> +			 Common pilot channel RX energy per chip over noise
> +			 density in dB.
> +			 Values: 0...63

Any better name than CPICH?

> +		int16 CPICH-RSCP [UTRA-FDD, optional]
> +			Common pilot channel RX carrier power in dBm
> +			Values: -4...127
> +
> +		byte Pathloss [UTRA-FDD, optional]
> +			Measured path loss in dB.
> +			Values: 46...173

Regards

Marcel



^ permalink raw reply

* Re: [PATCH 2/4] ARM: DT: Add a basic dts file for SMDKV310 machine
From: Rob Herring @ 2011-02-07 19:24 UTC (permalink / raw)
  To: David Gibson
  Cc: linaro-dev-cunTk1MwBs8s++Sfvej+rw,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	kgene.kim-Sze3O3UU22JBDgjK7y7TUQ, patches-QSEj5FYQhm4dnm+yROfE0A
In-Reply-To: <20110207000412.GA28953@yookeroo>

David, Thomas,

On 02/06/2011 06:04 PM, David Gibson wrote:
> On Sun, Feb 06, 2011 at 06:47:28PM +0530, Thomas Abraham wrote:
>> This patch adds a basic dts file for Samsung's SMDKV310 machine.
>>
>> Signed-off-by: Thomas Abraham<thomas.abraham-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
>> ---
>>   arch/arm/mach-s5pv310/mach-smdkv310.dts |   38 +++++++++++++++++++++++++++++++
>>   1 files changed, 38 insertions(+), 0 deletions(-)
>>   create mode 100755 arch/arm/mach-s5pv310/mach-smdkv310.dts
>>
>> diff --git a/arch/arm/mach-s5pv310/mach-smdkv310.dts b/arch/arm/mach-s5pv310/mach-smdkv310.dts
>> new file mode 100755
>> index 0000000..74d80bf
>> --- /dev/null
>> +++ b/arch/arm/mach-s5pv310/mach-smdkv310.dts
>> @@ -0,0 +1,38 @@
>> +/dts-v1/;
>> +
>> +/ {
>> +	model = "smdkv310";
>> +	compatible = "samsung,smdkv310";
>> +	#address-cells =<1>;
>> +	#size-cells =<1>;
>> +
>> +	memory {
>> +		device_type = "memory";
>> +		reg =<0x40000000 0x08000000>;
>> +	};
>
> Uh.. where are the cpus?
>

But for ARM, all the details of the cpu are probe-able. So what would we 
gain by putting cpu info in the DTS?

>> +	chosen {
>> +		bootargs = "root=/dev/ram0 rw ramdisk=8192 initrd=0x41000000,8M console=ttySAC1,115200 init=/linuxrc";
>> +	};
>> +
>> +	soc {
>> +		#address-cells =<1>;
>> +		#size-cells =<1>;
>> +		compatible = "simple-bus";
>
> It's generally a good idea to list the specific soc model before "simple-bus".
>
>> +		ranges =<0x00000000 0x00000000 0xFFFFFFFF>;

For no translation, you can do just:

ranges;

Rob

^ permalink raw reply

* Re: [PATCH/RFC] commit: fix memory-leak
From: Erik Faye-Lund @ 2011-02-07 19:22 UTC (permalink / raw)
  To: Matthieu Moy; +Cc: git, msysgit, blees
In-Reply-To: <vpqei7jfzq5.fsf@bauges.imag.fr>

On Mon, Feb 7, 2011 at 7:48 PM, Matthieu Moy
<Matthieu.Moy@grenoble-inp.fr> wrote:
> Erik Faye-Lund <kusmabite@gmail.com> writes:
>
>> At the same time, this fixes a problem with strict-POSIX getenv
>> implementations. POSIX says "The return value from getenv() may
>> point to static data which may be overwritten by subsequent calls
>> to getenv()", so duplicating the strings is a potential bug.
>                  ^
>                 not
> ?

Indeed, thanks.

^ permalink raw reply

* [PATCH] md_make_request: don't touch the bio after calling make_request
From: Chris Mason @ 2011-02-07 19:21 UTC (permalink / raw)
  To: linux-raid, linux-kernel; +Cc: axboe, neilb

md_make_request was calling bio_sectors() for part_stat_add
after it was calling the make_request function.  This is
bad because the make_request function can free the bio and
because the bi_size field can change around.

The fix here was suggested by Jens Axboe.  It saves the
sector count before the make_request call.  I hit this
with CONFIG_DEBUG_PAGEALLOC turned on while trying to break
his pretty fusionio card.

Signed-off-by: Chris Mason <chris.mason@oracle.com>
---
 drivers/md/md.c |    9 +++++++--
 1 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/md/md.c b/drivers/md/md.c
index b76cfc8..a7d3c3c 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -287,6 +287,7 @@ static int md_make_request(struct request_queue *q, struct bio *bio)
 	mddev_t *mddev = q->queuedata;
 	int rv;
 	int cpu;
+	unsigned int sectors;
 
 	if (mddev == NULL || mddev->pers == NULL
 	    || !mddev->ready) {
@@ -311,12 +312,16 @@ static int md_make_request(struct request_queue *q, struct bio *bio)
 	atomic_inc(&mddev->active_io);
 	rcu_read_unlock();
 
+	/*
+	 * save the sectors now since our bio can
+	 * go away inside make_request
+	 */
+	sectors = bio_sectors(bio);
 	rv = mddev->pers->make_request(mddev, bio);
 
 	cpu = part_stat_lock();
 	part_stat_inc(cpu, &mddev->gendisk->part0, ios[rw]);
-	part_stat_add(cpu, &mddev->gendisk->part0, sectors[rw],
-		      bio_sectors(bio));
+	part_stat_add(cpu, &mddev->gendisk->part0, sectors[rw], sectors);
 	part_stat_unlock();
 
 	if (atomic_dec_and_test(&mddev->active_io) && mddev->suspended)
-- 
1.7.1.1

^ permalink raw reply related

* Re: [PATCH V1 1/3] drivers/staging: kztmem: in-kernel tmem code
From: Konrad Rzeszutek Wilk @ 2011-02-07 16:02 UTC (permalink / raw)
  To: Dan Magenheimer
  Cc: gregkh, chris.mason, akpm, torvalds, matthew, linux-kernel,
	linux-mm, ngupta, jeremy, kurt.hackel, npiggin, riel, mel,
	minchan.kim, kosaki.motohiro, sfr, wfg, tytso, viro, hughd,
	hannes
In-Reply-To: <20110118171950.GA20460@ca-server1.us.oracle.com>

On Tue, Jan 18, 2011 at 09:19:50AM -0800, Dan Magenheimer wrote:
> [PATCH V1 1/3] drivers/staging: kztmem: in-kernel tmem code

Hey Dan,

I never finished this review, but sending my fragmented comments
in case the one you posted has overlap.

> 
> Transcendent memory ("tmem") is a clean API/ABI that provides
> for an efficient address translation and a set of highly
> concurrent access methods to copy data between a page-oriented
> data source (e.g. cleancache or frontswap) and a page-addressable
> memory ("PAM") data store.  Of critical importance, the PAM data
> store is of unknown (and possibly varying) size so any individual
> access may succeed or fail as defined by the API/ABI.
> 
> Tmem exports a basic set of access methods (e.g. put, get,
> flush, flush object, new pool, and destroy pool) which are
> normally called from a "host" (e.g. kztmem).
> 
> To be functional, two sets of "ops" must be registered by the
> host, one to provide "host services" (memory allocation) and
> one to provide page-addressable memory ("PAM") hooks.
> 
> Tmem supports one or more "clients", each which can provide
> a set of "pools" to partition pages.  Each pool contains
> a set of "objects"; each object holds pointers to some number
> of PAM page descriptors ("pampd"), indexed by an "index" number.
> This triple <pool id, object id, index> is sometimes referred
> to as a "handle".  Tmem's primary function is to essentially
> provide address translation of handles into pampds and move
> data appropriately.
> 
> As an example, for cleancache, a pool maps to a filesystem,
> an object maps to a file, and the index is the page offset
> into the file.  And in this patch, kztmem is the host and
> each PAM descriptor points to a compressed page of data.
> 
> Tmem supports two kinds of pages: "ephemeral" and "persistent".
> Ephemeral pages may be asynchronously reclaimed "bottoms up"
> so the data structures and concurrency model must allow for
> this.  For example, each pampd must retain sufficient information
> to invalidate tmem's handle-to-pampd translation.
> its containing object so that, on reclaim, all tmem data
> structures can be made consistent.
> 
> Signed-off-by: Dan Magenheimer <dan.magenheimer@oracle.com>
> 
> ---
> 
> Diffstat:
>  drivers/staging/kztmem/tmem.c            |  710 +++++++++++++++++++++
>  drivers/staging/kztmem/tmem.h            |  195 +++++
>  2 files changed, 905 insertions(+)
> --- linux-2.6.37/drivers/staging/kztmem/tmem.c	1969-12-31 17:00:00.000000000 -0700
> +++ linux-2.6.37-kztmem/drivers/staging/kztmem/tmem.c	2011-01-14 10:34:38.000000000 -0700
> @@ -0,0 +1,710 @@
> +/*
> + * In-kernel transcendent memory (generic implementation)
> + *
> + * Copyright (c) 2009-2011, Dan Magenheimer, Oracle Corp.
> + *
> + * The primary purpose of Transcedent Memory ("tmem") is to map object-oriented
> + * "handles" (triples containing a pool id, and object id, and an index), to
> + * pages in a page-accessible memory (PAM).  Tmem references the PAM pages via
> + * an abstract "pampd" (PAM page-descriptor), which can be operated on by a
> + * set of functions (pamops).  Each pampd contains some representation of
> + * PAGE_SIZE bytes worth of data. Tmem must support potentially millions of
> + * pages and must be able to insert, find, and delete these pages at a
> + * potential frequency of thousands per second concurrently across many CPUs,
> + * (and, if used with KVM, across many vcpus across many guests).
> + * Tmem is tracked with a hierarchy of data structures, organized by
> + * the elements in a handle-tuple: pool_id, object_id, and page index.
> + * One or more "clients" (e.g. guests) each provide one or more tmem_pools.
> + * Each pool, contains a hash table of rb_trees of tmem_objs.  Each
> + * tmem_obj contains a radix-tree-like tree of pointers, with intermediate
> + * nodes called tmem_objnodes.  Each leaf pointer in this tree points to
> + * a pampd, which is accessible only through a small set of callbacks
> + * registered by the PAM implementation (see tmem_register_pamops). Tmem
> + * does all memory allocation via a set of callbacks registered by the tmem
> + * host implementation (e.g. see tmem_register_hostops).
> + */
> +
> +#include <linux/list.h>
> +#include <linux/spinlock.h>
> +#include <linux/atomic.h>
> +
> +#include "tmem.h"
> +
> +/* data structure sentinels used for debugging... see tmem.h */
> +#define POOL_SENTINEL 0x87658765
> +#define OBJ_SENTINEL 0x12345678
> +#define OBJNODE_SENTINEL 0xfedcba09
> +
> +/*
> + * A tmem host implementation must use this function to register callbacks
> + * for memory allocation.
> + */
> +static struct tmem_hostops tmem_hostops;
> +
> +static void tmem_objnode_tree_init(void);
> +
> +void tmem_register_hostops(struct tmem_hostops *m)
> +{
> +	tmem_objnode_tree_init();
> +	tmem_hostops = *m;
> +}
> +
> +/*
> + * A tmem host implementation must use this function to register
> + * callbacks for a page-accessible memory (PAM) implementation
> + */
> +static struct tmem_pamops tmem_pamops;
> +
> +void tmem_register_pamops(struct tmem_pamops *m)
> +{
> +	tmem_pamops = *m;
> +}
> +
> +/*
> + * Oid's are potentially very sparse and tmem_objs may have an indeterminately
> + * short life, being added and deleted at a relatively high frequency.
> + * So an rb_tree is an ideal data structure to manage tmem_objs.  But because
> + * of the potentially huge number of tmem_objs, each pool manages a hashtable
> + * of rb_trees to reduce search, insert, delete, and rebalancing time.
> + * Each hashbucket also has a lock to manage concurrent access.
> + *
> + * The following routines manage tmem_objs.  When any tmem_obj is accessed,
> + * the hashbucket lock must be held.
> + */
> +
> +/* searches for object==oid in pool, returns locked object if found */
> +static struct tmem_obj *tmem_obj_find(struct tmem_hashbucket *hb,
> +					struct tmem_oid *oidp)
> +{
> +	struct rb_node *rbnode;
> +	struct tmem_obj *obj;
> +
> +	rbnode = hb->obj_rb_root.rb_node;
> +	while (rbnode) {
> +		BUG_ON(RB_EMPTY_NODE(rbnode));
> +		obj = rb_entry(rbnode, struct tmem_obj, rb_tree_node);
> +		switch (tmem_oid_compare(oidp, &obj->oid)) {
> +		case 0: /* equal */
> +			goto out;
> +		case -1:
> +			rbnode = rbnode->rb_left;
> +			break;
> +		case 1:
> +			rbnode = rbnode->rb_right;
> +			break;
> +		}
> +	}
> +	obj = NULL;
> +out:
> +	return obj;
> +}
> +
> +static void tmem_pampd_destroy_all_in_obj(struct tmem_obj *);
> +
> +/* free an object that has no more pampds in it */
> +static void tmem_obj_free(struct tmem_obj *obj, struct tmem_hashbucket *hb)
> +{
> +	struct tmem_pool *pool;
> +
> +	BUG_ON(obj == NULL);
> +	ASSERT_SENTINEL(obj, OBJ);
> +	BUG_ON(obj->pampd_count > 0);
> +	pool = obj->pool;
> +	BUG_ON(pool == NULL);
> +	if (obj->objnode_tree_root != NULL) /* may be "stump" with no leaves */
> +		tmem_pampd_destroy_all_in_obj(obj);
> +	BUG_ON(obj->objnode_tree_root != NULL);
> +	BUG_ON((long)obj->objnode_count != 0);
> +	atomic_dec(&pool->obj_count);
> +	BUG_ON(atomic_read(&pool->obj_count) < 0);
> +	INVERT_SENTINEL(obj, OBJ);
> +	obj->pool = NULL;
> +	tmem_oid_set_invalid(&obj->oid);
> +	rb_erase(&obj->rb_tree_node, &hb->obj_rb_root);
> +}
> +
> +/*
> + * initialize, and insert an tmem_object_root (called only if find failed)
> + */
> +static void tmem_obj_init(struct tmem_obj *obj, struct tmem_hashbucket *hb,
> +					struct tmem_pool *pool,
> +					struct tmem_oid *oidp)
> +{
> +	struct rb_root *root = &hb->obj_rb_root;
> +	struct rb_node **new = &(root->rb_node), *parent = NULL;
> +	struct tmem_obj *this;
> +
> +	BUG_ON(pool == NULL);
> +	atomic_inc(&pool->obj_count);
> +	obj->objnode_tree_height = 0;
> +	obj->objnode_tree_root = NULL;
> +	obj->pool = pool;
> +	obj->oid = *oidp;
> +	obj->objnode_count = 0;
> +	obj->pampd_count = 0;
> +	SET_SENTINEL(obj, OBJ);
> +	while (*new) {
> +		BUG_ON(RB_EMPTY_NODE(*new));
> +		this = rb_entry(*new, struct tmem_obj, rb_tree_node);
> +		parent = *new;
> +		switch (tmem_oid_compare(oidp, &this->oid)) {
> +		case 0:
> +			BUG(); /* already present; should never happen! */
> +			break;
> +		case -1:
> +			new = &(*new)->rb_left;
> +			break;
> +		case 1:
> +			new = &(*new)->rb_right;
> +			break;
> +		}
> +	}
> +	rb_link_node(&obj->rb_tree_node, parent, new);
> +	rb_insert_color(&obj->rb_tree_node, root);
> +}
> +
> +/*
> + * Tmem is managed as a set of tmem_pools with certain attributes, such as
> + * "ephemeral" vs "persistent".  These attributes apply to all tmem_objs
> + * and all pampds that belong to a tmem_pool.  A tmem_pool is created
> + * or deleted relatively rarely (for example, when a filesystem is
> + * mounted or unmounted.
> + */
> +
> +/* flush all data from a pool and, optionally, free it */
> +static void tmem_pool_flush(struct tmem_pool *pool, bool destroy)
> +{
> +	struct rb_node *rbnode;
> +	struct tmem_obj *obj;
> +	struct tmem_hashbucket *hb = &pool->hashbucket[0];
> +	int i;
> +
> +	BUG_ON(pool == NULL);
> +	for (i = 0; i < TMEM_HASH_BUCKETS; i++, hb++) {
> +		spin_lock(&hb->lock);
> +		rbnode = rb_first(&hb->obj_rb_root);
> +		while (rbnode != NULL) {
> +			obj = rb_entry(rbnode, struct tmem_obj, rb_tree_node);
> +			rbnode = rb_next(rbnode);
> +			tmem_pampd_destroy_all_in_obj(obj);
> +			tmem_obj_free(obj, hb);
> +			(*tmem_hostops.obj_free)(obj, pool);
> +		}
> +		spin_unlock(&hb->lock);
> +	}
> +	if (destroy)
> +		list_del(&pool->pool_list);
> +}
> +
> +/*
> + * A tmem_obj contains a radix-tree-like tree in which the intermediate
> + * nodes are called tmem_objnodes.  (The kernel lib/radix-tree.c implementation
> + * is very specialized and tuned for specific uses and is not particularly
> + * suited for use from this code, though some code from the core algorithms has
> + * been reused, thus the copyright notices below).  Each tmem_objnode contains
> + * a set of pointers which point to either a set of intermediate tmem_objnodes
> + * or a set of of pampds.
> + *
> + * Portions Copyright (C) 2001 Momchil Velikov
> + * Portions Copyright (C) 2001 Christoph Hellwig
> + * Portions Copyright (C) 2005 SGI, Christoph Lameter <clameter@sgi.com>
> + */
> +
> +struct tmem_objnode_tree_path {
> +	struct tmem_objnode *objnode;
> +	int offset;
> +};
> +
> +/* objnode height_to_maxindex translation */
> +static unsigned long tmem_objnode_tree_h2max[OBJNODE_TREE_MAX_PATH + 1];
> +
> +static void tmem_objnode_tree_init(void)
> +{
> +	unsigned int ht, tmp;
> +
> +	for (ht = 0; ht < ARRAY_SIZE(tmem_objnode_tree_h2max); ht++) {
> +		tmp = ht * OBJNODE_TREE_MAP_SHIFT;
> +		if (tmp >= OBJNODE_TREE_INDEX_BITS)
> +			tmem_objnode_tree_h2max[ht] = ~0UL;
> +		else
> +			tmem_objnode_tree_h2max[ht] =
> +			    (~0UL >> (OBJNODE_TREE_INDEX_BITS - tmp - 1)) >> 1;
> +	}
> +}
> +
> +static struct tmem_objnode *tmem_objnode_alloc(struct tmem_obj *obj)
> +{
> +	struct tmem_objnode *objnode;
> +
> +	ASSERT_SENTINEL(obj, OBJ);
> +	BUG_ON(obj->pool == NULL);
> +	ASSERT_SENTINEL(obj->pool, POOL);
> +	objnode = (*tmem_hostops.objnode_alloc)(obj->pool);
> +	if (unlikely(objnode == NULL))
> +		goto out;
> +	objnode->obj = obj;
> +	SET_SENTINEL(objnode, OBJNODE);
> +	memset(&objnode->slots, 0, sizeof(objnode->slots));
> +	objnode->slots_in_use = 0;
> +	obj->objnode_count++;
> +out:
> +	return objnode;
> +}
> +
> +static void tmem_objnode_free(struct tmem_objnode *objnode)
> +{
> +	struct tmem_pool *pool;
> +	int i;
> +
> +	BUG_ON(objnode == NULL);
> +	for (i = 0; i < OBJNODE_TREE_MAP_SIZE; i++)
> +		BUG_ON(objnode->slots[i] != NULL);
> +	ASSERT_SENTINEL(objnode, OBJNODE);
> +	INVERT_SENTINEL(objnode, OBJNODE);
> +	BUG_ON(objnode->obj == NULL);
> +	ASSERT_SENTINEL(objnode->obj, OBJ);
> +	pool = objnode->obj->pool;
> +	BUG_ON(pool == NULL);
> +	ASSERT_SENTINEL(pool, POOL);
> +	objnode->obj->objnode_count--;
> +	objnode->obj = NULL;
> +	(*tmem_hostops.objnode_free)(objnode, pool);
> +}
> +
> +/*
> + * lookup index in object and return associated pampd (or NULL if not found)
> + */
> +static void *tmem_pampd_lookup_in_obj(struct tmem_obj *obj, uint32_t index)
> +{
> +	unsigned int height, shift;
> +	struct tmem_objnode **slot = NULL;
> +
> +	BUG_ON(obj == NULL);
> +	ASSERT_SENTINEL(obj, OBJ);
> +	BUG_ON(obj->pool == NULL);
> +	ASSERT_SENTINEL(obj->pool, POOL);
> +
> +	height = obj->objnode_tree_height;
> +	if (index > tmem_objnode_tree_h2max[obj->objnode_tree_height])
> +		goto out;
> +	if (height == 0 && obj->objnode_tree_root) {
> +		slot = &obj->objnode_tree_root;
> +		goto out;
> +	}
> +	shift = (height-1) * OBJNODE_TREE_MAP_SHIFT;
> +	slot = &obj->objnode_tree_root;
> +	while (height > 0) {
> +		if (*slot == NULL)
> +			goto out;
> +		slot = (struct tmem_objnode **)
> +			((*slot)->slots +
> +			 ((index >> shift) & OBJNODE_TREE_MAP_MASK));
> +		shift -= OBJNODE_TREE_MAP_SHIFT;
> +		height--;
> +	}
> +out:
> +	return slot != NULL ? *slot : NULL;
> +}
> +
> +static int tmem_pampd_add_to_obj(struct tmem_obj *obj, uint32_t index,
> +					void *pampd)
> +{
> +	int ret = 0;
> +	struct tmem_objnode *objnode = NULL, *newnode, *slot;
> +	unsigned int height, shift;
> +	int offset = 0;
> +
> +	/* if necessary, extend the tree to be higher  */
> +	if (index > tmem_objnode_tree_h2max[obj->objnode_tree_height]) {
> +		height = obj->objnode_tree_height + 1;
> +		if (index > tmem_objnode_tree_h2max[height])
> +			while (index > tmem_objnode_tree_h2max[height])
> +				height++;
> +		if (obj->objnode_tree_root == NULL) {
> +			obj->objnode_tree_height = height;
> +			goto insert;
> +		}
> +		do {
> +			newnode = tmem_objnode_alloc(obj);
> +			if (!newnode) {
> +				ret = -ENOMEM;
> +				goto out;
> +			}
> +			newnode->slots[0] = obj->objnode_tree_root;
> +			newnode->slots_in_use = 1;
> +			obj->objnode_tree_root = newnode;
> +			obj->objnode_tree_height++;
> +		} while (height > obj->objnode_tree_height);
> +	}
> +insert:
> +	slot = obj->objnode_tree_root;
> +	height = obj->objnode_tree_height;
> +	shift = (height-1) * OBJNODE_TREE_MAP_SHIFT;
> +	while (height > 0) {
> +		if (slot == NULL) {
> +			/* add a child objnode.  */
> +			slot = tmem_objnode_alloc(obj);
> +			if (!slot) {
> +				ret = -ENOMEM;
> +				goto out;
> +			}
> +			if (objnode) {
> +
> +				objnode->slots[offset] = slot;
> +				objnode->slots_in_use++;
> +			} else
> +				obj->objnode_tree_root = slot;
> +		}
> +		/* go down a level */
> +		offset = (index >> shift) & OBJNODE_TREE_MAP_MASK;
> +		objnode = slot;
> +		slot = objnode->slots[offset];
> +		shift -= OBJNODE_TREE_MAP_SHIFT;
> +		height--;
> +	}
> +	BUG_ON(slot != NULL);
> +	if (objnode) {
> +		objnode->slots_in_use++;
> +		objnode->slots[offset] = pampd;
> +	} else
> +		obj->objnode_tree_root = pampd;
> +	obj->pampd_count++;
> +out:
> +	return ret;
> +}
> +
> +static void *tmem_pampd_delete_from_obj(struct tmem_obj *obj, uint32_t index)
> +{
> +	struct tmem_objnode_tree_path path[OBJNODE_TREE_MAX_PATH + 1];
> +	struct tmem_objnode_tree_path *pathp = path;
> +	struct tmem_objnode *slot = NULL;
> +	unsigned int height, shift;
> +	int offset;
> +
> +	BUG_ON(obj == NULL);
> +	ASSERT_SENTINEL(obj, OBJ);
> +	BUG_ON(obj->pool == NULL);

You could roll those two BUG_ON together.

> +	ASSERT_SENTINEL(obj->pool, POOL);
> +	height = obj->objnode_tree_height;
> +	if (index > tmem_objnode_tree_h2max[height])
> +		goto out;
> +	slot = obj->objnode_tree_root;
> +	if (height == 0 && obj->objnode_tree_root) {
> +		obj->objnode_tree_root = NULL;
> +		goto out;
> +	}
> +	shift = (height - 1) * OBJNODE_TREE_MAP_SHIFT;
> +	pathp->objnode = NULL;
> +	do {
> +		if (slot == NULL)
> +			goto out;
> +		pathp++;
> +		offset = (index >> shift) & OBJNODE_TREE_MAP_MASK;
> +		pathp->offset = offset;
> +		pathp->objnode = slot;
> +		slot = slot->slots[offset];
> +		shift -= OBJNODE_TREE_MAP_SHIFT;

> +		height--;
> +	} while (height > 0);
> +	if (slot == NULL)
> +		goto out;
> +	while (pathp->objnode) {
> +		pathp->objnode->slots[pathp->offset] = NULL;
> +		pathp->objnode->slots_in_use--;
> +		if (pathp->objnode->slots_in_use) {
> +			if (pathp->objnode == obj->objnode_tree_root) {
> +				while (obj->objnode_tree_height > 0 &&
> +				  obj->objnode_tree_root->slots_in_use == 1 &&
> +				  obj->objnode_tree_root->slots[0]) {
> +					struct tmem_objnode *to_free =
> +						obj->objnode_tree_root;
> +
> +					obj->objnode_tree_root =
> +							to_free->slots[0];
> +					obj->objnode_tree_height--;
> +					to_free->slots[0] = NULL;
> +					to_free->slots_in_use = 0;
> +					tmem_objnode_free(to_free);
> +				}
> +			}
> +			goto out;
> +		}
> +		tmem_objnode_free(pathp->objnode); /* 0 slots used, free it */
> +		pathp--;
> +	}
> +	obj->objnode_tree_height = 0;
> +	obj->objnode_tree_root = NULL;
> +
> +out:
> +	if (slot != NULL)
> +		obj->pampd_count--;
> +	BUG_ON(obj->pampd_count < 0);
> +	return slot;
> +}
> +
> +/* recursively walk the objnode_tree destroying pampds and objnodes */
> +static void tmem_objnode_node_destroy(struct tmem_obj *obj,
> +					struct tmem_objnode *objnode,
> +					unsigned int ht)
> +{
> +	int i;
> +
> +	if (ht == 0)
> +		return;
> +	for (i = 0; i < OBJNODE_TREE_MAP_SIZE; i++) {
> +		if (objnode->slots[i]) {
> +			if (ht == 1) {
> +				obj->pampd_count--;
> +				(*tmem_pamops.free)(objnode->slots[i],
> +								obj->pool);
> +				objnode->slots[i] = NULL;
> +				continue;
> +			}
> +			tmem_objnode_node_destroy(obj, objnode->slots[i], ht-1);
> +			tmem_objnode_free(objnode->slots[i]);
> +			objnode->slots[i] = NULL;
> +		}
> +	}
> +}
> +
> +static void tmem_pampd_destroy_all_in_obj(struct tmem_obj *obj)
> +{
> +	if (obj->objnode_tree_root == NULL)
> +		return;
> +	if (obj->objnode_tree_height == 0) {
> +		obj->pampd_count--;
> +		(*tmem_pamops.free)(obj->objnode_tree_root, obj->pool);
> +	} else {
> +		tmem_objnode_node_destroy(obj, obj->objnode_tree_root,
> +					obj->objnode_tree_height);
> +		tmem_objnode_free(obj->objnode_tree_root);
> +		obj->objnode_tree_height = 0;
> +	}
> +	obj->objnode_tree_root = NULL;
> +}
> +
> +/*
> + * Tmem is operated on by a set of well-defined actions:
> + * "put", "get", "flush", "flush_object", "new pool" and "destroy pool".
> + * (The tmem ABI allows for subpages and exchanges but these operations
> + * are not included in this implementation.)
> + *
> + * These "tmem core" operations are implemented in the following functions.
> + */
> +
> +/*
> + * "Put" a page, e.g. copy a page from the kernel into newly allocated
> + * PAM space (if such space is available).  Tmem_put is complicated by
> + * a corner case: What if a page with matching handle already exists in
> + * tmem?  To guarantee coherency, one of two actions is necessary: Either
> + * the data for the page must be overwritten, or the page must be
> + * "flushed" so that the data is not accessible to a subsequent "get".
> + * Since these "duplicate puts" are relatively rare, this implementation
> + * always flushes for simplicity.
> + */
> +int tmem_put(struct tmem_pool *pool, struct tmem_oid *oidp, uint32_t index,
> +		struct page *page)
> +{
> +	struct tmem_obj *obj = NULL, *objfound = NULL, *objnew = NULL;
> +	void *pampd = NULL, *pampd_del = NULL;
> +	int ret = -ENOMEM;
> +	bool ephemeral;
> +	struct tmem_hashbucket *hb;
> +
> +	ephemeral = is_ephemeral(pool);
> +	hb = &pool->hashbucket[tmem_oid_hash(oidp)];
> +	spin_lock(&hb->lock);
> +	obj = objfound = tmem_obj_find(hb, oidp);
> +	if (obj != NULL) {
> +		pampd = tmem_pampd_lookup_in_obj(objfound, index);
> +		if (pampd != NULL) {
> +			/* if found, is a dup put, flush the old one */
> +			pampd_del = tmem_pampd_delete_from_obj(obj, index);
> +			BUG_ON(pampd_del != pampd);
> +			(*tmem_pamops.free)(pampd, pool);
> +			if (obj->pampd_count == 0) {
> +				objnew = obj;
> +				objfound = NULL;
> +			}
> +			pampd = NULL;
> +		}
> +	} else {
> +		obj = objnew = (*tmem_hostops.obj_alloc)(pool);
> +		if (unlikely(obj == NULL)) {
> +			ret = -ENOMEM;
> +			goto out;
> +		}
> +		tmem_obj_init(obj, hb, pool, oidp);
> +	}
> +	BUG_ON(obj == NULL);
> +	BUG_ON(((objnew != obj) && (objfound != obj)) || (objnew == objfound));
> +	pampd = (*tmem_pamops.create)(obj->pool, &obj->oid, index, page);
> +	if (unlikely(pampd == NULL))
> +		goto free;
> +	ret = tmem_pampd_add_to_obj(obj, index, pampd);
> +	if (unlikely(ret == -ENOMEM))
> +		/* may have partially built objnode tree ("stump") */
> +		goto delete_and_free;
> +	goto out;
> +
> +delete_and_free:
> +	(void)tmem_pampd_delete_from_obj(obj, index);
> +free:
> +	if (pampd)
> +		(*tmem_pamops.free)(pampd, pool);
> +	if (objnew) {
> +		tmem_obj_free(objnew, hb);
> +		(*tmem_hostops.obj_free)(objnew, pool);
> +	}
> +out:
> +	spin_unlock(&hb->lock);
> +	return ret;
> +}
> +
> +/*
> + * "Get" a page, e.g. if one can be found, copy the tmem page with the
> + * matching handle from PAM space to the kernel.  By tmem definition,
> + * when a "get" is successful on an ephemeral page, the page is "flushed",
> + * and when a "get" is successful on a persistent page, the page is retained

persistent and ephemeral pages can both be in PAM space?

> + * in tmem.  Note that to preserve
> + * coherency, "get" can never be skipped if tmem contains the data.
> + * That is, if a get is done with a certain handle and fails, any
> + * subsequent "get" must also fail (unless of course there is a
> + * "put" done with the same handle).
> +
> + */
> +int tmem_get(struct tmem_pool *pool, struct tmem_oid *oidp,
> +				uint32_t index, struct page *page)
> +{
> +	struct tmem_obj *obj;
> +	void *pampd;
> +	bool ephemeral = is_ephemeral(pool);
> +	uint32_t ret = -1;

Hmm, uint32_t and -1 ? I think you meant 'int'

> +	struct tmem_hashbucket *hb;
> +
> +	hb = &pool->hashbucket[tmem_oid_hash(oidp)];
> +	spin_lock(&hb->lock);
> +	obj = tmem_obj_find(hb, oidp);
> +	if (obj == NULL)
> +		goto out;
> +	ephemeral = is_ephemeral(pool);

Didn't you alrady check for that earlier?

> +	if (ephemeral)
> +		pampd = tmem_pampd_delete_from_obj(obj, index);
> +	else
> +		pampd = tmem_pampd_lookup_in_obj(obj, index);
> +	if (pampd == NULL)
> +		goto out;
> +	ret = (*tmem_pamops.get_data)(page, pampd, pool);
> +	if (ret < 0)
> +		goto out;
> +	if (ephemeral) {
> +		(*tmem_pamops.free)(pampd, pool);
> +		if (obj->pampd_count == 0) {
> +			tmem_obj_free(obj, hb);
> +			(*tmem_hostops.obj_free)(obj, pool);
> +			obj = NULL;
> +		}
> +	}
> +	ret = 0;
> +out:
> +	spin_unlock(&hb->lock);
> +	return ret;
> +}
> +
> +/*
> + * If a page in tmem matches the handle, "flush" this page from tmem such
> + * that any subsequent "get" does not succeed (unless, of course, there
> + * was another "put" with the same handle).
> + */
> +int tmem_flush_page(struct tmem_pool *pool,
> +				struct tmem_oid *oidp, uint32_t index)
> +{
> +	struct tmem_obj *obj;
> +	void *pampd;
> +	int ret = -1;
-ENODEV?
> +	struct tmem_hashbucket *hb;
> +
> +	hb = &pool->hashbucket[tmem_oid_hash(oidp)];
> +	spin_lock(&hb->lock);
> +	obj = tmem_obj_find(hb, oidp);
> +	if (obj == NULL)
> +		goto out;
> +	pampd = tmem_pampd_delete_from_obj(obj, index);
> +	if (pampd == NULL)
> +		goto out;
> +	(*tmem_pamops.free)(pampd, pool);
> +	if (obj->pampd_count == 0) {
> +		tmem_obj_free(obj, hb);
> +		(*tmem_hostops.obj_free)(obj, pool);
> +	}
> +	ret = 0;
> +
> +out:
> +	spin_unlock(&hb->lock);
> +	return ret;
> +}
> +
> +/*
> + * "Flush" all pages in tmem matching this oid.
> + */
> +int tmem_flush_object(struct tmem_pool *pool, struct tmem_oid *oidp)
> +{
> +	struct tmem_obj *obj;
> +	struct tmem_hashbucket *hb;
> +	int ret = -1;

How about -ENODEV?

We don't want to check the oidp using the  tmem_oid_valid
just in case the value provided is bogus? This way we
can omit using the spin_lock and right away quit?

I guess it would not matter much as we would still
> +
> +	hb = &pool->hashbucket[tmem_oid_hash(oidp)];
> +	spin_lock(&hb->lock);
> +	obj = tmem_obj_find(hb, oidp);
> +	if (obj == NULL)

..get to here and goto out..
> +		goto out;
> +	tmem_pampd_destroy_all_in_obj(obj);
> +	tmem_obj_free(obj, hb);
> +	(*tmem_hostops.obj_free)(obj, pool);
> +	ret = 0;
> +
> +out:
> +	spin_unlock(&hb->lock);
> +	return ret;
> +}
> +
> +/*
> + * "Flush" all pages (and tmem_objs) from this tmem_pool and disable
> + * all subsequent access to this tmem_pool.

Take the 'all' out.

> + */
> +int tmem_destroy_pool(struct tmem_pool *pool)
> +{
> +	int ret = -1;

Hmm, -ENODEV?
> +
> +	if (pool == NULL)
> +		goto out;
> +	tmem_pool_flush(pool, 1);
> +	ret = 0;
> +out:
> +	return ret;
> +}
> +
> +static LIST_HEAD(tmem_global_pool_list);
> +
> +/*
> + * Create a new tmem_pool with the provided flag and return
> + * a pool id provided by the tmem host implementation.

Not seeing the return.
> + */
> +void tmem_new_pool(struct tmem_pool *pool, uint32_t flags)
> +{
> +	int persistent = flags & TMEM_POOL_PERSIST;
> +	int shared = flags & TMEM_POOL_SHARED;
> +	struct tmem_hashbucket *hb = &pool->hashbucket[0];
> +	int i;
> +
> +	for (i = 0; i < TMEM_HASH_BUCKETS; i++, hb++) {
> +		hb->obj_rb_root = RB_ROOT;
> +		spin_lock_init(&hb->lock);
> +	}
> +	INIT_LIST_HEAD(&pool->pool_list);
> +	atomic_set(&pool->obj_count, 0);
> +	SET_SENTINEL(pool, POOL);
> +	list_add_tail(&pool->pool_list, &tmem_global_pool_list);
> +	pool->persistent = persistent;
> +	pool->shared = shared;
> +}
> --- linux-2.6.37/drivers/staging/kztmem/tmem.h	1969-12-31 17:00:00.000000000 -0700
> +++ linux-2.6.37-kztmem/drivers/staging/kztmem/tmem.h	2011-01-14 10:34:32.000000000 -0700
> @@ -0,0 +1,195 @@
> +/*
> + * tmem.h
> + *
> + * Transcendent memory
> + *
> + * Copyright (c) 2009-2011, Dan Magenheimer, Oracle Corp.
> + */
> +
> +#ifndef _TMEM_H_
> +#define _TMEM_H_
> +
> +#include <linux/types.h>
> +#include <linux/highmem.h>
> +#include <linux/hash.h>
> +#include <linux/atomic.h>
> +
> +/*
> + * These are pre-defined by the Xen<->Linux ABI
> + */
> +#define TMEM_PUT_PAGE			4
> +#define TMEM_GET_PAGE			5
> +#define TMEM_FLUSH_PAGE			6
> +#define TMEM_FLUSH_OBJECT		7
> +#define TMEM_POOL_PERSIST		1
> +#define TMEM_POOL_SHARED		2
> +#define TMEM_POOL_PRECOMPRESSED		4
> +#define TMEM_POOL_PAGESIZE_SHIFT	4
> +#define TMEM_POOL_PAGESIZE_MASK		0xf
> +#define TMEM_POOL_RESERVED_BITS		0x00ffff00
> +
> +/*
> + * sentinels have proven very useful for debugging but can be removed
> + * or disabled before final merge.
> + */
> +#define SENTINELS
> +#ifdef SENTINELS
> +#define DECL_SENTINEL uint32_t sentinel;
> +#define SET_SENTINEL(_x, _y) (_x->sentinel = _y##_SENTINEL)
> +#define INVERT_SENTINEL(_x, _y) (_x->sentinel = ~_y##_SENTINEL)
> +#define ASSERT_SENTINEL(_x, _y) WARN_ON(_x->sentinel != _y##_SENTINEL)
> +#define ASSERT_INVERTED_SENTINEL(_x, _y) WARN_ON(_x->sentinel != ~_y##_SENTINEL)
> +#else
> +#define DECL_SENTINEL
> +#define SET_SENTINEL(_x, _y) do { } while (0)
> +#define INVERT_SENTINEL(_x, _y) do { } while (0)
> +#define ASSERT_SENTINEL(_x, _y) do { } while (0)
> +#define ASSERT_INVERTED_SENTINEL(_x, _y) do { } while (0)
> +#endif
> +
> +#define ASSERT_SPINLOCK(_l)	WARN_ON(!spin_is_locked(_l))
> +
> +/*
> + * A pool is the highest-level data structure managed by tmem and
> + * usually corresponds to a large independent set of pages such as
> + * a filesystem.  Each pool has an id, and certain attributes and counters.
> + * It also contains a set of hash buckets, each of which contains an rbtree
> + * of objects and a lock to manage concurrency within the pool.
> + */
> +
> +#define TMEM_HASH_BUCKET_BITS	8
> +#define TMEM_HASH_BUCKETS	(1<<TMEM_HASH_BUCKET_BITS)
> +
> +struct tmem_hashbucket {
> +	struct rb_root obj_rb_root;
> +	spinlock_t lock;
> +};
> +
> +struct tmem_pool {
> +	void *client; /* "up" for some clients, avoids table lookup */
> +	struct list_head pool_list;
> +	uint32_t pool_id;
> +	bool persistent;
> +	bool shared;
> +	atomic_t obj_count;
> +	atomic_t refcount;
> +	struct tmem_hashbucket hashbucket[TMEM_HASH_BUCKETS];
> +	DECL_SENTINEL
> +};
> +
> +#define is_persistent(_p)  (_p->persistent)
> +#define is_ephemeral(_p)   (!(_p->persistent))
> +
> +/*
> + * An object id ("oid") is large: 192-bits (to ensure, for example, files
> + * in a modern filesystem can be uniquely identified).
> + */
> +
> +struct tmem_oid {
> +	uint64_t oid[3];
> +};
> +
> +static inline void tmem_oid_set_invalid(struct tmem_oid *oidp)
> +{
> +	oidp->oid[0] = oidp->oid[1] = oidp->oid[2] = -1UL;
> +}
> +
> +static inline bool tmem_oid_valid(struct tmem_oid *oidp)
> +{
> +	return oidp->oid[0] != -1UL || oidp->oid[1] != -1UL ||
> +		oidp->oid[2] != -1UL;
> +}
> +
> +static inline int tmem_oid_compare(struct tmem_oid *left,
> +					struct tmem_oid *right)
> +{
> +	int ret;
> +
> +	if (left->oid[2] == right->oid[2]) {
> +		if (left->oid[1] == right->oid[1]) {
> +			if (left->oid[0] == right->oid[0])
> +				ret = 0;
> +			else if (left->oid[0] < right->oid[0])
> +				ret = -1;
> +			else
> +				return 1;
> +		} else if (left->oid[1] < right->oid[1])
> +			ret = -1;
> +		else
> +			ret = 1;
> +	} else if (left->oid[2] < right->oid[2])
> +		ret = -1;
> +	else
> +		ret = 1;
> +	return ret;
> +}
> +
> +static inline unsigned tmem_oid_hash(struct tmem_oid *oidp)
> +{
> +	return hash_long(oidp->oid[0] ^ oidp->oid[1] ^ oidp->oid[2],
> +				TMEM_HASH_BUCKET_BITS);
> +}
> +
> +/*
> + * A tmem_obj contains an identifier (oid), pointers to the parent
> + * pool and the rb_tree to which it belongs, counters, and an ordered
> + * set of pampds, structured in a radix-tree-like tree.  The intermediate
> + * nodes of the tree are called tmem_objnodes.
> + */
> +
> +struct tmem_objnode;
> +
> +struct tmem_obj {
> +	struct tmem_oid oid;
> +	struct tmem_pool *pool;
> +	struct rb_node rb_tree_node;
> +	struct tmem_objnode *objnode_tree_root;
> +	unsigned int objnode_tree_height;
> +	unsigned long objnode_count;
> +	long pampd_count;
> +	DECL_SENTINEL
> +};
> +
> +#define OBJNODE_TREE_MAP_SHIFT 6
> +#define OBJNODE_TREE_MAP_SIZE (1UL << OBJNODE_TREE_MAP_SHIFT)
> +#define OBJNODE_TREE_MAP_MASK (OBJNODE_TREE_MAP_SIZE-1)
> +#define OBJNODE_TREE_INDEX_BITS (8 /* CHAR_BIT */ * sizeof(unsigned long))
> +#define OBJNODE_TREE_MAX_PATH \
> +		(OBJNODE_TREE_INDEX_BITS/OBJNODE_TREE_MAP_SHIFT + 2)
> +
> +struct tmem_objnode {
> +	struct tmem_obj *obj;
> +	DECL_SENTINEL
> +	void *slots[OBJNODE_TREE_MAP_SIZE];
> +	unsigned int slots_in_use;
> +};
> +
> +/* pampd abstract datatype methods provided by the PAM implementation */
> +struct tmem_pamops {
> +	void *(*create)(struct tmem_pool *, struct tmem_oid *, uint32_t,
> +			struct page *);
> +	int (*get_data)(struct page *, void *, struct tmem_pool *);
> +	void (*free)(void *, struct tmem_pool *);
> +};
> +extern void tmem_register_pamops(struct tmem_pamops *m);
> +
> +/* memory allocation methods provided by the host implementation */
> +struct tmem_hostops {
> +	struct tmem_obj *(*obj_alloc)(struct tmem_pool *);
> +	void (*obj_free)(struct tmem_obj *, struct tmem_pool *);
> +	struct tmem_objnode *(*objnode_alloc)(struct tmem_pool *);
> +	void (*objnode_free)(struct tmem_objnode *, struct tmem_pool *);
> +};
> +extern void tmem_register_hostops(struct tmem_hostops *m);
> +
> +/* core tmem accessor functions */
> +extern int tmem_put(struct tmem_pool *, struct tmem_oid *, uint32_t index,
> +			struct page *page);
> +extern int tmem_get(struct tmem_pool *, struct tmem_oid *, uint32_t index,
> +			struct page *page);
> +extern int tmem_flush_page(struct tmem_pool *, struct tmem_oid *,
> +			uint32_t index);
> +extern int tmem_flush_object(struct tmem_pool *, struct tmem_oid *);
> +extern int tmem_destroy_pool(struct tmem_pool *);
> +extern void tmem_new_pool(struct tmem_pool *, uint32_t);
> +#endif /* _TMEM_H */

^ permalink raw reply

* [PATCH] bonding/vlan: Avoid mangled NAs on slaves without VLAN tag insertion
From: Ben Hutchings @ 2011-02-07 19:20 UTC (permalink / raw)
  To: stable; +Cc: Jay Vosburgh, David Miller, netdev, bonding-devel

This is related to commit f88a4a9b65a6f3422b81be995535d0e69df11bb8
upstream, but the bug cannot be properly fixed without the other
changes to VLAN tagging in 2.6.37.

bond_na_send() attempts to insert a VLAN tag in between building and
sending packets of the respective formats.  If the slave does not
implement hardware VLAN tag insertion then vlan_put_tag() will mangle
the network-layer header because the Ethernet header is not present at
this point (unlike in bond_arp_send()).

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
This fix is applicable to versions [2.6.29, 2.6.36].  The context for
the second hunk needs to be reduced to 1 line for versions < 2.6.33
(git am -C1) as the logging call was changed.

Ben.

 drivers/net/bonding/bond_ipv6.c |    9 ++++++++-
 1 files changed, 8 insertions(+), 1 deletions(-)

diff --git a/drivers/net/bonding/bond_ipv6.c b/drivers/net/bonding/bond_ipv6.c
index 121b073..78eb5fa 100644
--- a/drivers/net/bonding/bond_ipv6.c
+++ b/drivers/net/bonding/bond_ipv6.c
@@ -70,6 +70,13 @@ static void bond_na_send(struct net_device *slave_dev,
 	};
 	struct sk_buff *skb;
 
+	/* The Ethernet header is built in ndisc_send_skb(), not
+	 * ndisc_build_skb(), so we cannot insert a VLAN tag.  Only an
+	 * out-of-line tag inserted by the hardware will work.
+	 */
+	if (vlan_id && !(slave_dev->features & NETIF_F_HW_VLAN_TX))
+		return;
+
 	icmp6h.icmp6_router = router;
 	icmp6h.icmp6_solicited = 0;
 	icmp6h.icmp6_override = 1;
@@ -88,7 +95,7 @@ static void bond_na_send(struct net_device *slave_dev,
 	}
 
 	if (vlan_id) {
-		skb = vlan_put_tag(skb, vlan_id);
+		skb = __vlan_hwaccel_put_tag(skb, vlan_id);
 		if (!skb) {
 			pr_err("failed to insert VLAN tag\n");
 			return;
-- 
1.7.2.3


-- 
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.


^ permalink raw reply related

* Re: [PATCH] x86/mm/init: respect memblock reserved regions when destroying mappings
From: Yinghai Lu @ 2011-02-07 19:18 UTC (permalink / raw)
  To: Stefano Stabellini
  Cc: H. Peter Anvin, Jeremy Fitzhardinge, linux-kernel@vger.kernel.org,
	tglx@linutronix.de, x86@kernel.org, Konrad Rzeszutek Wilk,
	Jan Beulich
In-Reply-To: <4D504161.2060900@kernel.org>

On Mon, Feb 7, 2011 at 11:00 AM, Yinghai Lu <yinghai@kernel.org> wrote:
> On 02/07/2011 10:58 AM, Stefano Stabellini wrote:
>> On Mon, 7 Feb 2011, Yinghai Lu wrote:
>>> On 02/07/2011 08:50 AM, Stefano Stabellini wrote:
>>>> On Sun, 6 Feb 2011, Yinghai Lu wrote:
>>>>> On 02/05/2011 11:30 PM, H. Peter Anvin wrote:
>>>>>> On 02/05/2011 11:02 PM, Yinghai Lu wrote:
>>>>>>> why not just move calling cleanup_highmap down?
>>>>>>>
>>>>>>> something like attached patch.
>>>>>>
>>>>>> This patch looks very clean and looks on the surface of it like it is
>>>>>> removing some ugly ad hoc code, but (as always) it needs a description
>>>>>> about the problem it solves and why it is correct.
>>>>>
>>>>> Sure.
>>>>>
>>>>>
>>>>> Jeremy and xen guys, can you please check if it works well with xen ?
>>>>>
>>>>
>>>> Actually this patch makes things worse on xen, because before
>>>> cleanup_highmap() wasn't called at all on xen (on purpose) and now it
>>>> is, fully destroying all the mappings we have at _end.
>>>>
>>>> Can we add a check on memblock reserved regions in cleanup_highmap()?
>>>> Otherwise could we avoid calling cleanup_highmap() at all on xen?
>>>
>>> why DO xen need over-mapped kernel initial mapping?
>>>
>>> what is in that range after _end to 512M?
>>
>> The mfn list that is the list of machine frame numbers assigned to this
>> domain; it is used across the kernel to convert pfns into mfns.
>> It passed to us at that address by the domain builder.
>
> is it possible for you to pass physical address, and then map it in kernel?


or

wonder if you can use really kernel mapping for your mfn list
accessing instead of initial mapping accessing?

something like:
mfn_list = __va(__pa(initial_mfn_...);


Yinghai

^ permalink raw reply

* Trouble Shooting ipsec
From: Stephen Clark @ 2011-02-07 19:17 UTC (permalink / raw)
  To: Linux Kernel Network Developers

Hello,

How do I find out what is happening to my packets thru my ipsec tunnel.
They just seem to disappear on the remote side.

I have successfully got the pings thru
when everything has an ipv6 address, but am not successful when trying
to connect two ipv4 lans across an ipv6 ipsec tunnel. All fw chains both 
4 and 6
are set to ACCEPT. NAT is turned off.

      eth0               eth1                                         
eth1                 eth0
10.1.254.254/17  2001:xxxx:1628::254 <----ipv6 internet -----> 
2001:xxxx:e334::254  10.0.254.254/17

12:00:02.296972 IP6 2001:xxxx:1628::254 > 2001:xxxx:e334::254: 
ESP(spi=0x07454bc3,seq=0x28b), length 132
12:00:03.308751 IP6 2001:xxxx:1628::254 > 2001:xxxx:e334::254: 
ESP(spi=0x07454bc3,seq=0x28c), length 132
12:00:04.296857 IP6 2001:xxxx:1628::254 > 2001:xxxx:e334::254: 
ESP(spi=0x07454bc3,seq=0x28d), length 132
12:00:05.293748 IP6 2001:xxxx:1628::254 > 2001:xxxx:e334::254: 
ESP(spi=0x07454bc3,seq=0x28e), length 132
12:00:06.296623 IP6 2001:xxxx:1628::254 > 2001:xxxx:e334::254: 
ESP(spi=0x07454bc3,seq=0x28f), length 132

I have posted to the ipsec-devel list and haven't gotten any responses. 
Also I have spent 2 days googling with
no results about the above setup. Is it even possible to tunnel ipv4 
packet thru an ipv6 ipsec tunnel?

Thanks,
Steve

-- 

"They that give up essential liberty to obtain temporary safety,
deserve neither liberty nor safety."  (Ben Franklin)

"The course of history shows that as a government grows, liberty
decreases."  (Thomas Jefferson)




^ permalink raw reply

* Re: [PATCH] PM: Hide CONFIG_PM from users
From: Rafael J. Wysocki @ 2011-02-07 19:16 UTC (permalink / raw)
  To: Mark Brown
  Cc: Stephen Rothwell, linux-embedded, Len Brown, Dmitry Torokhov,
	linux-kernel, Geert Uytterhoeven, linux-pm, ppc-dev,
	Andrew Morton
In-Reply-To: <20110207154953.GN10564@opensource.wolfsonmicro.com>

On Monday, February 07, 2011, Mark Brown wrote:
> On Mon, Feb 07, 2011 at 10:36:31AM -0500, Alan Stern wrote:
> > On Mon, 7 Feb 2011, Mark Brown wrote:
> 
> > > I'd not be so sure - since it's a bool without an explicit default set
> > > Kconfig will default to disabling it and if anything enabling it is the
> > > option that requires special effort.
> 
> > This may be a naive suggestion, but have you considered simply _asking_
> > the people who added those defconfigs?
> 
> I'm rather hoping that they'll notice the mailing list thread or that
> someone else who knows what's going on with them does - as Geert pointed
> out there's a considerable number of defconfigs that have this turned
> off.  It seems more sensible to get some idea if this seems sane to
> people in the general case before going trying to identify and contact
> so many individuals.
> 
> If there are systems that really require disabling CONFIG_PM we probably
> need to add stuff to Kconfig to make sure it can't be enabled anyway;
> this shouldn't enable any new configurations.

Well, as I've just said, I don't like this change.  I'd very much prefer it if
CONFIG_PM_OPS were renamed to CONFIG_PM.

Thanks,
Rafael

^ permalink raw reply

* Re: [PATCH] PM: Hide CONFIG_PM from users
From: Rafael J. Wysocki @ 2011-02-07 19:16 UTC (permalink / raw)
  To: Mark Brown
  Cc: Alan Stern, Stephen Rothwell, Geert Uytterhoeven, Len Brown,
	linux-pm, linux-kernel, Andrew Morton, Dmitry Torokhov,
	linux-embedded, ppc-dev
In-Reply-To: <20110207154953.GN10564@opensource.wolfsonmicro.com>

On Monday, February 07, 2011, Mark Brown wrote:
> On Mon, Feb 07, 2011 at 10:36:31AM -0500, Alan Stern wrote:
> > On Mon, 7 Feb 2011, Mark Brown wrote:
> 
> > > I'd not be so sure - since it's a bool without an explicit default set
> > > Kconfig will default to disabling it and if anything enabling it is the
> > > option that requires special effort.
> 
> > This may be a naive suggestion, but have you considered simply _asking_
> > the people who added those defconfigs?
> 
> I'm rather hoping that they'll notice the mailing list thread or that
> someone else who knows what's going on with them does - as Geert pointed
> out there's a considerable number of defconfigs that have this turned
> off.  It seems more sensible to get some idea if this seems sane to
> people in the general case before going trying to identify and contact
> so many individuals.
> 
> If there are systems that really require disabling CONFIG_PM we probably
> need to add stuff to Kconfig to make sure it can't be enabled anyway;
> this shouldn't enable any new configurations.

Well, as I've just said, I don't like this change.  I'd very much prefer it if
CONFIG_PM_OPS were renamed to CONFIG_PM.

Thanks,
Rafael

^ permalink raw reply

* Re: [PATCH] embedded 1288 fcbga arrandale cpu not detected in ips module - no gpu turbo
From: Jesse Barnes @ 2011-02-07 19:16 UTC (permalink / raw)
  To: Matthew Garrett
  Cc: Koerber, Philip (GE Intelligent Platforms), platform-driver-x86
In-Reply-To: <20110207191321.GA19838@srcf.ucam.org>

On Mon, 7 Feb 2011 19:13:21 +0000
Matthew Garrett <mjg59@srcf.ucam.org> wrote:

> On Fri, Feb 04, 2011 at 09:11:56AM -0800, Jesse Barnes wrote:
> > > +++ linux/drivers/platform/x86/intel_ips.c	2011-02-04 15:25:40.205627688 +0100
> > > @@ -1399,6 +1399,10 @@
> > >  		limits = &ips_lv_limits;
> > >  	else if (strstr(boot_cpu_data.x86_model_id, "CPU       U"))
> > >  		limits = &ips_ulv_limits;
> > > +	else if (strstr(boot_cpu_data.x86_model_id, "CPU         610"))
> > > +		limits = &ips_sv_limits;
> > > +	else if (strstr(boot_cpu_data.x86_model_id, "CPU         520"))
> > > +		limits = &ips_sv_limits;
> > >  	else {
> > >  		dev_info(&ips->dev->dev, "No CPUID match found.\n");
> > >  		goto out;
> > 
> > Yep, that's fine with me, thanks for the patch!
> 
> Are these the only two embedded Arrandales? Is there really no MSR that 
> gives you the voltage range?

AFAIK this is the same method the Windows driver uses, so I don't think
so.

Fortunately the on-die integration in Sandy Bridge makes all this
unnecessary, so I don't expect you'll have to continually add entries
to this list over time.

-- 
Jesse Barnes, Intel Open Source Technology Center

^ permalink raw reply

* Re: [PATCH] PM: Hide CONFIG_PM from users
From: Rafael J. Wysocki @ 2011-02-07 19:14 UTC (permalink / raw)
  To: Mark Brown
  Cc: Len Brown, linux-embedded, Dmitry Torokhov, linux-kernel,
	Ingo Molnar, linux-pm, Andrew Morton
In-Reply-To: <1297081335-13631-1-git-send-email-broonie@opensource.wolfsonmicro.com>

On Monday, February 07, 2011, Mark Brown wrote:
> It is very rare to find a current system which is both sufficiently
> resource constrained to want to compile out power management support
> and sufficiently power insensitive to be able to tolerate doing so.
> Since having the configuration option requires non-zero effort to
> maintain, with ifdefery in most drivers, but it is used with vanishing
> rarity it is simpler to just remove the option.
> 
> Begin doing so by hiding it from users - this should attract complaints
> from any active users. The option is left disabled for the IA64 Ski
> simulator which is a partial simulator for IA64 systems mostly missing
> device support. This is a very limited use case which is unlikely to
> ever want to enable most drivers.
> 
> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
> ---
>  kernel/power/Kconfig |   21 ++-------------------
>  1 files changed, 2 insertions(+), 19 deletions(-)
> 
> diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
> index 2657299..99e3c52 100644
> --- a/kernel/power/Kconfig
> +++ b/kernel/power/Kconfig
> @@ -1,23 +1,6 @@
>  config PM
> -	bool "Power Management support"
> -	depends on !IA64_HP_SIM
> -	---help---
> -	  "Power Management" means that parts of your computer are shut
> -	  off or put into a power conserving "sleep" mode if they are not
> -	  being used.  There are two competing standards for doing this: APM
> -	  and ACPI.  If you want to use either one, say Y here and then also
> -	  to the requisite support below.
> -
> -	  Power Management is most important for battery powered laptop
> -	  computers; if you have a laptop, check out the Linux Laptop home
> -	  page on the WWW at <http://www.linux-on-laptops.com/> or
> -	  Tuxmobil - Linux on Mobile Computers at <http://www.tuxmobil.org/>
> -	  and the Battery Powered Linux mini-HOWTO, available from
> -	  <http://www.tldp.org/docs.html#howto>.
> -
> -	  Note that, even if you say N here, Linux on the x86 architecture
> -	  will issue the hlt instruction if nothing is to be done, thereby
> -	  sending the processor to sleep and saving power.
> +	bool
> +	default y if !IA64_HP_SIM
>  
>  config PM_DEBUG
>  	bool "Power Management Debug Support"

I think it would be better to simply rename CONFIG_PM_OPS into CONFIG_PM.

However, there's a number of things that I'm afraid wouldn't build correctly
if none of CONFIG_PM_SLEEP and CONFIG_PM_RUNTIME were set in that case.

Anyway, I'll try to prepare a patch doing that and see what happens.
Stay tuned.

Thanks,
Rafael

^ permalink raw reply

* Re: [PATCH] PM: Hide CONFIG_PM from users
From: Rafael J. Wysocki @ 2011-02-07 19:14 UTC (permalink / raw)
  To: Mark Brown
  Cc: Len Brown, Alan Stern, linux-pm, linux-kernel, Andrew Morton,
	Dmitry Torokhov, linux-embedded, Ingo Molnar
In-Reply-To: <1297081335-13631-1-git-send-email-broonie@opensource.wolfsonmicro.com>

On Monday, February 07, 2011, Mark Brown wrote:
> It is very rare to find a current system which is both sufficiently
> resource constrained to want to compile out power management support
> and sufficiently power insensitive to be able to tolerate doing so.
> Since having the configuration option requires non-zero effort to
> maintain, with ifdefery in most drivers, but it is used with vanishing
> rarity it is simpler to just remove the option.
> 
> Begin doing so by hiding it from users - this should attract complaints
> from any active users. The option is left disabled for the IA64 Ski
> simulator which is a partial simulator for IA64 systems mostly missing
> device support. This is a very limited use case which is unlikely to
> ever want to enable most drivers.
> 
> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
> ---
>  kernel/power/Kconfig |   21 ++-------------------
>  1 files changed, 2 insertions(+), 19 deletions(-)
> 
> diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
> index 2657299..99e3c52 100644
> --- a/kernel/power/Kconfig
> +++ b/kernel/power/Kconfig
> @@ -1,23 +1,6 @@
>  config PM
> -	bool "Power Management support"
> -	depends on !IA64_HP_SIM
> -	---help---
> -	  "Power Management" means that parts of your computer are shut
> -	  off or put into a power conserving "sleep" mode if they are not
> -	  being used.  There are two competing standards for doing this: APM
> -	  and ACPI.  If you want to use either one, say Y here and then also
> -	  to the requisite support below.
> -
> -	  Power Management is most important for battery powered laptop
> -	  computers; if you have a laptop, check out the Linux Laptop home
> -	  page on the WWW at <http://www.linux-on-laptops.com/> or
> -	  Tuxmobil - Linux on Mobile Computers at <http://www.tuxmobil.org/>
> -	  and the Battery Powered Linux mini-HOWTO, available from
> -	  <http://www.tldp.org/docs.html#howto>.
> -
> -	  Note that, even if you say N here, Linux on the x86 architecture
> -	  will issue the hlt instruction if nothing is to be done, thereby
> -	  sending the processor to sleep and saving power.
> +	bool
> +	default y if !IA64_HP_SIM
>  
>  config PM_DEBUG
>  	bool "Power Management Debug Support"

I think it would be better to simply rename CONFIG_PM_OPS into CONFIG_PM.

However, there's a number of things that I'm afraid wouldn't build correctly
if none of CONFIG_PM_SLEEP and CONFIG_PM_RUNTIME were set in that case.

Anyway, I'll try to prepare a patch doing that and see what happens.
Stay tuned.

Thanks,
Rafael

^ permalink raw reply

* Re: [PATCH] embedded 1288 fcbga arrandale cpu not detected in ips module - no gpu turbo
From: Matthew Garrett @ 2011-02-07 19:13 UTC (permalink / raw)
  To: Jesse Barnes
  Cc: Koerber, Philip (GE Intelligent Platforms), platform-driver-x86
In-Reply-To: <20110204091156.1b8e76fb@jbarnes-desktop>

On Fri, Feb 04, 2011 at 09:11:56AM -0800, Jesse Barnes wrote:
> > +++ linux/drivers/platform/x86/intel_ips.c	2011-02-04 15:25:40.205627688 +0100
> > @@ -1399,6 +1399,10 @@
> >  		limits = &ips_lv_limits;
> >  	else if (strstr(boot_cpu_data.x86_model_id, "CPU       U"))
> >  		limits = &ips_ulv_limits;
> > +	else if (strstr(boot_cpu_data.x86_model_id, "CPU         610"))
> > +		limits = &ips_sv_limits;
> > +	else if (strstr(boot_cpu_data.x86_model_id, "CPU         520"))
> > +		limits = &ips_sv_limits;
> >  	else {
> >  		dev_info(&ips->dev->dev, "No CPUID match found.\n");
> >  		goto out;
> 
> Yep, that's fine with me, thanks for the patch!

Are these the only two embedded Arrandales? Is there really no MSR that 
gives you the voltage range?

-- 
Matthew Garrett | mjg59@srcf.ucam.org

^ permalink raw reply

* Re: Patched up cthon source?
From: Jim Rees @ 2011-02-07 19:13 UTC (permalink / raw)
  To: Jeff Layton
  Cc: Bryan Schumaker, Benny Halevy, Chuck Lever, Thomas Haynes,
	linux-nfs
In-Reply-To: <20110125095649.446212fd-9yPaYZwiELC+kQycOl6kW4xkIHaj4LzF@public.gmane.org>

Jeff Layton wrote:

  On Tue, 25 Jan 2011 08:43:25 -0500
  Bryan Schumaker <bjschuma@netapp.com> wrote:
  
  > On 01/24/2011 05:33 PM, Benny Halevy wrote:
  > > this is a problem with the version of nroff on newer distributions.
  > 
  > My version of groff (1.21) is splitting the error into two lines, so I am using the following patch.
  > 
  > Bryan
  > 
  
  Yep, this workaround stopped working around for me on my rawhide box
  broke yesterday for the same reason.
  
  I think this patch may be a better approach than trying to grep out
  random stuff, but I don't know whether non-GNU tbl programs will barf
  on it. If anyone has a solaris box handy, could you let me know if
  this breaks on it?

Your patch does not work for me on Ubuntu with groff 1.20.1.

^ permalink raw reply

* Re: [patch] ALSA: soc-cache: dereferencing before checking
From: Liam Girdwood @ 2011-02-07 19:11 UTC (permalink / raw)
  To: Dan Carpenter; +Cc: Takashi Iwai, alsa-devel, Mark Brown, kernel-janitors
In-Reply-To: <20110207190141.GJ4384@bicker>

On Mon, 2011-02-07 at 22:01 +0300, Dan Carpenter wrote:
> The patch c358e640a66 "ASoC: soc-cache: Add trace event for
> snd_soc_cache_sync()" introduced a dereference of "codec->cache_ops"
> before we had checked it for NULL.
> 
> I pulled the check forward, and then pulled everything in an indent
> level.
> 
> Signed-off-by: Dan Carpenter <error27@gmail.com>

Acked-by: Liam Girdwood <lrg@slimlogic.co.uk>
-- 
Freelance Developer, SlimLogic Ltd
ASoC and Voltage Regulator Maintainer.
http://www.slimlogic.co.uk

^ permalink raw reply

* Re: [alsa-devel] [patch] ALSA: soc-cache: dereferencing before
From: Liam Girdwood @ 2011-02-07 19:11 UTC (permalink / raw)
  To: Dan Carpenter; +Cc: Takashi Iwai, alsa-devel, Mark Brown, kernel-janitors
In-Reply-To: <20110207190141.GJ4384@bicker>

On Mon, 2011-02-07 at 22:01 +0300, Dan Carpenter wrote:
> The patch c358e640a66 "ASoC: soc-cache: Add trace event for
> snd_soc_cache_sync()" introduced a dereference of "codec->cache_ops"
> before we had checked it for NULL.
> 
> I pulled the check forward, and then pulled everything in an indent
> level.
> 
> Signed-off-by: Dan Carpenter <error27@gmail.com>

Acked-by: Liam Girdwood <lrg@slimlogic.co.uk>
-- 
Freelance Developer, SlimLogic Ltd
ASoC and Voltage Regulator Maintainer.
http://www.slimlogic.co.uk


^ permalink raw reply

* Re: [PATCH] ASoC: codecs: wm8753: Fix DAI mode switching
From: Mark Brown @ 2011-02-07 19:11 UTC (permalink / raw)
  To: Liam Girdwood; +Cc: Lars-Peter Clausen, alsa-devel, linux-kernel
In-Reply-To: <1297105825.3331.353.camel@odin>

On Mon, Feb 07, 2011 at 07:10:25PM +0000, Liam Girdwood wrote:

> Acked-by: Liam Girdwood <lrg@slimlogic.co.uk>

Applied, thanks.

^ permalink raw reply

* Re: [PATCH] ASoC: codecs: wm8753: Fix DAI mode switching
From: Mark Brown @ 2011-02-07 19:11 UTC (permalink / raw)
  To: Liam Girdwood; +Cc: alsa-devel, Lars-Peter Clausen, linux-kernel
In-Reply-To: <1297105825.3331.353.camel@odin>

On Mon, Feb 07, 2011 at 07:10:25PM +0000, Liam Girdwood wrote:

> Acked-by: Liam Girdwood <lrg@slimlogic.co.uk>

Applied, thanks.

^ permalink raw reply


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.