forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[POWERPC] spufs: Add infrastructure needed for gang scheduling
Add the concept of a gang to spufs as a new type of object. So far, this has no impact whatsover on scheduling, but makes it possible to add that later. A new type of object in spufs is now a spu_gang. It is created with the spu_create system call with the flags argument set to SPU_CREATE_GANG (0x2). Inside of a spu_gang, it is then possible to create spu_context objects, which until now was only possible at the root of spufs. There is a new member in struct spu_context pointing to the spu_gang it belongs to, if any. The spu_gang maintains a list of spu_context structures that are its children. This information can then be used in the scheduler in the future. There is still a bug that needs to be resolved in this basic infrastructure regarding the order in which objects are removed. When the spu_gang file descriptor is closed before the spu_context descriptors, we leak the dentry and inode for the gang. Any ideas how to cleanly solve this are appreciated. Signed-off-by: Arnd Bergmann <[email protected]> Signed-off-by: Paul Mackerras <[email protected]>
- Loading branch information
1 parent
9add11d
commit 6263203
Showing
7 changed files
with
303 additions
and
42 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
/* | ||
* SPU file system | ||
* | ||
* (C) Copyright IBM Deutschland Entwicklung GmbH 2005 | ||
* | ||
* Author: Arnd Bergmann <[email protected]> | ||
* | ||
* This program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation; either version 2, or (at your option) | ||
* any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program; if not, write to the Free Software | ||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
*/ | ||
|
||
#include <linux/list.h> | ||
#include <linux/slab.h> | ||
|
||
#include "spufs.h" | ||
|
||
struct spu_gang *alloc_spu_gang(void) | ||
{ | ||
struct spu_gang *gang; | ||
|
||
gang = kzalloc(sizeof *gang, GFP_KERNEL); | ||
if (!gang) | ||
goto out; | ||
|
||
kref_init(&gang->kref); | ||
mutex_init(&gang->mutex); | ||
INIT_LIST_HEAD(&gang->list); | ||
|
||
out: | ||
return gang; | ||
} | ||
|
||
static void destroy_spu_gang(struct kref *kref) | ||
{ | ||
struct spu_gang *gang; | ||
gang = container_of(kref, struct spu_gang, kref); | ||
WARN_ON(gang->contexts || !list_empty(&gang->list)); | ||
kfree(gang); | ||
} | ||
|
||
struct spu_gang *get_spu_gang(struct spu_gang *gang) | ||
{ | ||
kref_get(&gang->kref); | ||
return gang; | ||
} | ||
|
||
int put_spu_gang(struct spu_gang *gang) | ||
{ | ||
return kref_put(&gang->kref, &destroy_spu_gang); | ||
} | ||
|
||
void spu_gang_add_ctx(struct spu_gang *gang, struct spu_context *ctx) | ||
{ | ||
mutex_lock(&gang->mutex); | ||
ctx->gang = get_spu_gang(gang); | ||
list_add(&ctx->gang_list, &gang->list); | ||
gang->contexts++; | ||
mutex_unlock(&gang->mutex); | ||
} | ||
|
||
void spu_gang_remove_ctx(struct spu_gang *gang, struct spu_context *ctx) | ||
{ | ||
mutex_lock(&gang->mutex); | ||
WARN_ON(ctx->gang != gang); | ||
list_del_init(&ctx->gang_list); | ||
gang->contexts--; | ||
mutex_unlock(&gang->mutex); | ||
|
||
put_spu_gang(gang); | ||
} |
Oops, something went wrong.