Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
595f403c
Commit
595f403c
authored
Apr 30, 2008
by
Paul Mackerras
Browse files
Options
Browse Files
Download
Plain Diff
Merge
git://git.kernel.org/pub/scm/linux/kernel/git/jk/spufs
parents
82225252
d0eb801c
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
226 additions
and
21 deletions
+226
-21
arch/powerpc/platforms/cell/spufs/.gitignore
arch/powerpc/platforms/cell/spufs/.gitignore
+2
-0
arch/powerpc/platforms/cell/spufs/context.c
arch/powerpc/platforms/cell/spufs/context.c
+4
-0
arch/powerpc/platforms/cell/spufs/file.c
arch/powerpc/platforms/cell/spufs/file.c
+166
-0
arch/powerpc/platforms/cell/spufs/run.c
arch/powerpc/platforms/cell/spufs/run.c
+2
-0
arch/powerpc/platforms/cell/spufs/sched.c
arch/powerpc/platforms/cell/spufs/sched.c
+3
-1
arch/powerpc/platforms/cell/spufs/spufs.h
arch/powerpc/platforms/cell/spufs/spufs.h
+31
-2
arch/powerpc/platforms/cell/spufs/sputrace.c
arch/powerpc/platforms/cell/spufs/sputrace.c
+18
-18
No files found.
arch/powerpc/platforms/cell/spufs/.gitignore
0 → 100644
View file @
595f403c
spu_save_dump.h
spu_restore_dump.h
arch/powerpc/platforms/cell/spufs/context.c
View file @
595f403c
...
...
@@ -78,6 +78,7 @@ void destroy_spu_context(struct kref *kref)
{
struct
spu_context
*
ctx
;
ctx
=
container_of
(
kref
,
struct
spu_context
,
kref
);
spu_context_nospu_trace
(
destroy_spu_context__enter
,
ctx
);
mutex_lock
(
&
ctx
->
state_mutex
);
spu_deactivate
(
ctx
);
mutex_unlock
(
&
ctx
->
state_mutex
);
...
...
@@ -88,6 +89,7 @@ void destroy_spu_context(struct kref *kref)
kref_put
(
ctx
->
prof_priv_kref
,
ctx
->
prof_priv_release
);
BUG_ON
(
!
list_empty
(
&
ctx
->
rq
));
atomic_dec
(
&
nr_spu_contexts
);
kfree
(
ctx
->
switch_log
);
kfree
(
ctx
);
}
...
...
@@ -150,6 +152,8 @@ int spu_acquire_saved(struct spu_context *ctx)
{
int
ret
;
spu_context_nospu_trace
(
spu_acquire_saved__enter
,
ctx
);
ret
=
spu_acquire
(
ctx
);
if
(
ret
)
return
ret
;
...
...
arch/powerpc/platforms/cell/spufs/file.c
View file @
595f403c
...
...
@@ -2386,6 +2386,171 @@ static const struct file_operations spufs_stat_fops = {
.
release
=
single_release
,
};
static
inline
int
spufs_switch_log_used
(
struct
spu_context
*
ctx
)
{
return
(
ctx
->
switch_log
->
head
-
ctx
->
switch_log
->
tail
)
%
SWITCH_LOG_BUFSIZE
;
}
static
inline
int
spufs_switch_log_avail
(
struct
spu_context
*
ctx
)
{
return
SWITCH_LOG_BUFSIZE
-
spufs_switch_log_used
(
ctx
);
}
static
int
spufs_switch_log_open
(
struct
inode
*
inode
,
struct
file
*
file
)
{
struct
spu_context
*
ctx
=
SPUFS_I
(
inode
)
->
i_ctx
;
/*
* We (ab-)use the mapping_lock here because it serves the similar
* purpose for synchronizing open/close elsewhere. Maybe it should
* be renamed eventually.
*/
mutex_lock
(
&
ctx
->
mapping_lock
);
if
(
ctx
->
switch_log
)
{
spin_lock
(
&
ctx
->
switch_log
->
lock
);
ctx
->
switch_log
->
head
=
0
;
ctx
->
switch_log
->
tail
=
0
;
spin_unlock
(
&
ctx
->
switch_log
->
lock
);
}
else
{
/*
* We allocate the switch log data structures on first open.
* They will never be free because we assume a context will
* be traced until it goes away.
*/
ctx
->
switch_log
=
kzalloc
(
sizeof
(
struct
switch_log
)
+
SWITCH_LOG_BUFSIZE
*
sizeof
(
struct
switch_log_entry
),
GFP_KERNEL
);
if
(
!
ctx
->
switch_log
)
goto
out
;
spin_lock_init
(
&
ctx
->
switch_log
->
lock
);
init_waitqueue_head
(
&
ctx
->
switch_log
->
wait
);
}
mutex_unlock
(
&
ctx
->
mapping_lock
);
return
0
;
out:
mutex_unlock
(
&
ctx
->
mapping_lock
);
return
-
ENOMEM
;
}
static
int
switch_log_sprint
(
struct
spu_context
*
ctx
,
char
*
tbuf
,
int
n
)
{
struct
switch_log_entry
*
p
;
p
=
ctx
->
switch_log
->
log
+
ctx
->
switch_log
->
tail
%
SWITCH_LOG_BUFSIZE
;
return
snprintf
(
tbuf
,
n
,
"%u.%09u %d %u %u %llu
\n
"
,
(
unsigned
int
)
p
->
tstamp
.
tv_sec
,
(
unsigned
int
)
p
->
tstamp
.
tv_nsec
,
p
->
spu_id
,
(
unsigned
int
)
p
->
type
,
(
unsigned
int
)
p
->
val
,
(
unsigned
long
long
)
p
->
timebase
);
}
static
ssize_t
spufs_switch_log_read
(
struct
file
*
file
,
char
__user
*
buf
,
size_t
len
,
loff_t
*
ppos
)
{
struct
inode
*
inode
=
file
->
f_path
.
dentry
->
d_inode
;
struct
spu_context
*
ctx
=
SPUFS_I
(
inode
)
->
i_ctx
;
int
error
=
0
,
cnt
=
0
;
if
(
!
buf
||
len
<
0
)
return
-
EINVAL
;
while
(
cnt
<
len
)
{
char
tbuf
[
128
];
int
width
;
if
(
file
->
f_flags
&
O_NONBLOCK
)
{
if
(
spufs_switch_log_used
(
ctx
)
<=
0
)
return
cnt
?
cnt
:
-
EAGAIN
;
}
else
{
/* Wait for data in buffer */
error
=
wait_event_interruptible
(
ctx
->
switch_log
->
wait
,
spufs_switch_log_used
(
ctx
)
>
0
);
if
(
error
)
break
;
}
spin_lock
(
&
ctx
->
switch_log
->
lock
);
if
(
ctx
->
switch_log
->
head
==
ctx
->
switch_log
->
tail
)
{
/* multiple readers race? */
spin_unlock
(
&
ctx
->
switch_log
->
lock
);
continue
;
}
width
=
switch_log_sprint
(
ctx
,
tbuf
,
sizeof
(
tbuf
));
if
(
width
<
len
)
{
ctx
->
switch_log
->
tail
=
(
ctx
->
switch_log
->
tail
+
1
)
%
SWITCH_LOG_BUFSIZE
;
}
spin_unlock
(
&
ctx
->
switch_log
->
lock
);
/*
* If the record is greater than space available return
* partial buffer (so far)
*/
if
(
width
>=
len
)
break
;
error
=
copy_to_user
(
buf
+
cnt
,
tbuf
,
width
);
if
(
error
)
break
;
cnt
+=
width
;
}
return
cnt
==
0
?
error
:
cnt
;
}
static
unsigned
int
spufs_switch_log_poll
(
struct
file
*
file
,
poll_table
*
wait
)
{
struct
inode
*
inode
=
file
->
f_path
.
dentry
->
d_inode
;
struct
spu_context
*
ctx
=
SPUFS_I
(
inode
)
->
i_ctx
;
unsigned
int
mask
=
0
;
poll_wait
(
file
,
&
ctx
->
switch_log
->
wait
,
wait
);
if
(
spufs_switch_log_used
(
ctx
)
>
0
)
mask
|=
POLLIN
;
return
mask
;
}
static
const
struct
file_operations
spufs_switch_log_fops
=
{
.
owner
=
THIS_MODULE
,
.
open
=
spufs_switch_log_open
,
.
read
=
spufs_switch_log_read
,
.
poll
=
spufs_switch_log_poll
,
};
void
spu_switch_log_notify
(
struct
spu
*
spu
,
struct
spu_context
*
ctx
,
u32
type
,
u32
val
)
{
if
(
!
ctx
->
switch_log
)
return
;
spin_lock
(
&
ctx
->
switch_log
->
lock
);
if
(
spufs_switch_log_avail
(
ctx
)
>
1
)
{
struct
switch_log_entry
*
p
;
p
=
ctx
->
switch_log
->
log
+
ctx
->
switch_log
->
head
;
ktime_get_ts
(
&
p
->
tstamp
);
p
->
timebase
=
get_tb
();
p
->
spu_id
=
spu
?
spu
->
number
:
-
1
;
p
->
type
=
type
;
p
->
val
=
val
;
ctx
->
switch_log
->
head
=
(
ctx
->
switch_log
->
head
+
1
)
%
SWITCH_LOG_BUFSIZE
;
}
spin_unlock
(
&
ctx
->
switch_log
->
lock
);
wake_up
(
&
ctx
->
switch_log
->
wait
);
}
struct
tree_descr
spufs_dir_contents
[]
=
{
{
"capabilities"
,
&
spufs_caps_fops
,
0444
,
},
...
...
@@ -2422,6 +2587,7 @@ struct tree_descr spufs_dir_contents[] = {
{
"proxydma_info"
,
&
spufs_proxydma_info_fops
,
0444
,
},
{
"tid"
,
&
spufs_tid_fops
,
0444
,
},
{
"stat"
,
&
spufs_stat_fops
,
0444
,
},
{
"switch_log"
,
&
spufs_switch_log_fops
,
0444
},
{},
};
...
...
arch/powerpc/platforms/cell/spufs/run.c
View file @
595f403c
...
...
@@ -405,6 +405,8 @@ long spufs_run_spu(struct spu_context *ctx, u32 *npc, u32 *event)
ret
=
spu_run_fini
(
ctx
,
npc
,
&
status
);
spu_yield
(
ctx
);
spu_switch_log_notify
(
NULL
,
ctx
,
SWITCH_LOG_EXIT
,
status
);
if
((
status
&
SPU_STATUS_STOPPED_BY_STOP
)
&&
(((
status
>>
SPU_STOP_STATUS_SHIFT
)
&
0x3f00
)
==
0x2100
))
ctx
->
stats
.
libassist
++
;
...
...
arch/powerpc/platforms/cell/spufs/sched.c
View file @
595f403c
...
...
@@ -240,6 +240,7 @@ static void spu_bind_context(struct spu *spu, struct spu_context *ctx)
spu
->
mfc_callback
=
spufs_mfc_callback
;
mb
();
spu_unmap_mappings
(
ctx
);
spu_switch_log_notify
(
spu
,
ctx
,
SWITCH_LOG_START
,
0
);
spu_restore
(
&
ctx
->
csa
,
spu
);
spu
->
timestamp
=
jiffies
;
spu_cpu_affinity_set
(
spu
,
raw_smp_processor_id
());
...
...
@@ -419,6 +420,7 @@ static void spu_unbind_context(struct spu *spu, struct spu_context *ctx)
spu_switch_notify
(
spu
,
NULL
);
spu_unmap_mappings
(
ctx
);
spu_save
(
&
ctx
->
csa
,
spu
);
spu_switch_log_notify
(
spu
,
ctx
,
SWITCH_LOG_STOP
,
0
);
spu
->
timestamp
=
jiffies
;
ctx
->
state
=
SPU_STATE_SAVED
;
spu
->
ibox_callback
=
NULL
;
...
...
@@ -591,7 +593,7 @@ static struct spu *find_victim(struct spu_context *ctx)
struct
spu
*
spu
;
int
node
,
n
;
spu_context_nospu_trace
(
spu_find_vitim__enter
,
ctx
);
spu_context_nospu_trace
(
spu_find_vi
c
tim__enter
,
ctx
);
/*
* Look for a possible preemption candidate on the local node first.
...
...
arch/powerpc/platforms/cell/spufs/spufs.h
View file @
595f403c
...
...
@@ -47,6 +47,30 @@ enum {
SPU_SCHED_SPU_RUN
,
/* context is within spu_run */
};
enum
{
SWITCH_LOG_BUFSIZE
=
4096
,
};
enum
{
SWITCH_LOG_START
,
SWITCH_LOG_STOP
,
SWITCH_LOG_EXIT
,
};
struct
switch_log
{
spinlock_t
lock
;
wait_queue_head_t
wait
;
unsigned
long
head
;
unsigned
long
tail
;
struct
switch_log_entry
{
struct
timespec
tstamp
;
s32
spu_id
;
u32
type
;
u32
val
;
u64
timebase
;
}
log
[];
};
struct
spu_context
{
struct
spu
*
spu
;
/* pointer to a physical SPU */
struct
spu_state
csa
;
/* SPU context save area. */
...
...
@@ -116,6 +140,9 @@ struct spu_context {
unsigned
long
long
libassist
;
}
stats
;
/* context switch log */
struct
switch_log
*
switch_log
;
struct
list_head
aff_list
;
int
aff_head
;
int
aff_offset
;
...
...
@@ -256,6 +283,8 @@ int spu_activate(struct spu_context *ctx, unsigned long flags);
void
spu_deactivate
(
struct
spu_context
*
ctx
);
void
spu_yield
(
struct
spu_context
*
ctx
);
void
spu_switch_notify
(
struct
spu
*
spu
,
struct
spu_context
*
ctx
);
void
spu_switch_log_notify
(
struct
spu
*
spu
,
struct
spu_context
*
ctx
,
u32
type
,
u32
val
);
void
spu_set_timeslice
(
struct
spu_context
*
ctx
);
void
spu_update_sched_info
(
struct
spu_context
*
ctx
);
void
__spu_update_sched_info
(
struct
spu_context
*
ctx
);
...
...
@@ -330,8 +359,8 @@ extern void spuctx_switch_state(struct spu_context *ctx,
enum
spu_utilization_state
new_state
);
#define spu_context_trace(name, ctx, spu) \
trace_mark(name, "
%p
%p", ctx, spu);
trace_mark(name, "
ctx %p spu
%p", ctx, spu);
#define spu_context_nospu_trace(name, ctx) \
trace_mark(name, "%p", ctx);
trace_mark(name, "
ctx
%p", ctx);
#endif
arch/powerpc/platforms/cell/spufs/sputrace.c
View file @
595f403c
...
...
@@ -171,24 +171,24 @@ static void spu_context_nospu_event(void *probe_private, void *call_data,
}
struct
spu_probe
spu_probes
[]
=
{
{
"spu_bind_context__enter"
,
"
%p
%p"
,
spu_context_event
},
{
"spu_unbind_context__enter"
,
"
%p
%p"
,
spu_context_event
},
{
"spu_get_idle__enter"
,
"%p"
,
spu_context_nospu_event
},
{
"spu_get_idle__found"
,
"
%p
%p"
,
spu_context_event
},
{
"spu_get_idle__not_found"
,
"%p"
,
spu_context_nospu_event
},
{
"spu_find_victim__enter"
,
"%p"
,
spu_context_nospu_event
},
{
"spusched_tick__preempt"
,
"
%p
%p"
,
spu_context_event
},
{
"spusched_tick__newslice"
,
"%p"
,
spu_context_nospu_event
},
{
"spu_yield__enter"
,
"%p"
,
spu_context_nospu_event
},
{
"spu_deactivate__enter"
,
"%p"
,
spu_context_nospu_event
},
{
"__spu_deactivate__unload"
,
"
%p
%p"
,
spu_context_event
},
{
"spufs_ps_nopfn__enter"
,
"%p"
,
spu_context_nospu_event
},
{
"spufs_ps_nopfn__sleep"
,
"%p"
,
spu_context_nospu_event
},
{
"spufs_ps_nopfn__wake"
,
"
%p
%p"
,
spu_context_event
},
{
"spufs_ps_nopfn__insert"
,
"
%p
%p"
,
spu_context_event
},
{
"spu_acquire_saved__enter"
,
"%p"
,
spu_context_nospu_event
},
{
"destroy_spu_context__enter"
,
"%p"
,
spu_context_nospu_event
},
{
"spufs_stop_callback__enter"
,
"
%p
%p"
,
spu_context_event
},
{
"spu_bind_context__enter"
,
"
ctx %p spu
%p"
,
spu_context_event
},
{
"spu_unbind_context__enter"
,
"
ctx %p spu
%p"
,
spu_context_event
},
{
"spu_get_idle__enter"
,
"
ctx
%p"
,
spu_context_nospu_event
},
{
"spu_get_idle__found"
,
"
ctx %p spu
%p"
,
spu_context_event
},
{
"spu_get_idle__not_found"
,
"
ctx
%p"
,
spu_context_nospu_event
},
{
"spu_find_victim__enter"
,
"
ctx
%p"
,
spu_context_nospu_event
},
{
"spusched_tick__preempt"
,
"
ctx %p spu
%p"
,
spu_context_event
},
{
"spusched_tick__newslice"
,
"
ctx
%p"
,
spu_context_nospu_event
},
{
"spu_yield__enter"
,
"
ctx
%p"
,
spu_context_nospu_event
},
{
"spu_deactivate__enter"
,
"
ctx
%p"
,
spu_context_nospu_event
},
{
"__spu_deactivate__unload"
,
"
ctx %p spu
%p"
,
spu_context_event
},
{
"spufs_ps_nopfn__enter"
,
"
ctx
%p"
,
spu_context_nospu_event
},
{
"spufs_ps_nopfn__sleep"
,
"
ctx
%p"
,
spu_context_nospu_event
},
{
"spufs_ps_nopfn__wake"
,
"
ctx %p spu
%p"
,
spu_context_event
},
{
"spufs_ps_nopfn__insert"
,
"
ctx %p spu
%p"
,
spu_context_event
},
{
"spu_acquire_saved__enter"
,
"
ctx
%p"
,
spu_context_nospu_event
},
{
"destroy_spu_context__enter"
,
"
ctx
%p"
,
spu_context_nospu_event
},
{
"spufs_stop_callback__enter"
,
"
ctx %p spu
%p"
,
spu_context_event
},
};
static
int
__init
sputrace_init
(
void
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment