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
f8f3d12d
Commit
f8f3d12d
authored
Oct 11, 2003
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge
bk://kernel.bkbits.net/davem/sparc-2.5
into home.osdl.org:/home/torvalds/v2.5/linux
parents
8dd9d072
348e9f70
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
41 additions
and
9 deletions
+41
-9
arch/i386/kernel/timers/timer_tsc.c
arch/i386/kernel/timers/timer_tsc.c
+2
-2
kernel/timer.c
kernel/timer.c
+39
-7
No files found.
arch/i386/kernel/timers/timer_tsc.c
View file @
f8f3d12d
...
@@ -321,7 +321,7 @@ time_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
...
@@ -321,7 +321,7 @@ time_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
{
{
struct
cpufreq_freqs
*
freq
=
data
;
struct
cpufreq_freqs
*
freq
=
data
;
write_seqlock
(
&
xtime_lock
);
write_seqlock
_irq
(
&
xtime_lock
);
if
(
!
ref_freq
)
{
if
(
!
ref_freq
)
{
ref_freq
=
freq
->
old
;
ref_freq
=
freq
->
old
;
loops_per_jiffy_ref
=
cpu_data
[
freq
->
cpu
].
loops_per_jiffy
;
loops_per_jiffy_ref
=
cpu_data
[
freq
->
cpu
].
loops_per_jiffy
;
...
@@ -342,7 +342,7 @@ time_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
...
@@ -342,7 +342,7 @@ time_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
}
}
#endif
#endif
}
}
write_sequnlock
(
&
xtime_lock
);
write_sequnlock
_irq
(
&
xtime_lock
);
return
0
;
return
0
;
}
}
...
...
kernel/timer.c
View file @
f8f3d12d
...
@@ -315,23 +315,30 @@ EXPORT_SYMBOL(del_timer);
...
@@ -315,23 +315,30 @@ EXPORT_SYMBOL(del_timer);
* the timer it also makes sure the handler has finished executing on other
* the timer it also makes sure the handler has finished executing on other
* CPUs.
* CPUs.
*
*
* Synchronization rules: callers must prevent restarting of the timer,
* Synchronization rules: callers must prevent restarting of the timer
* otherwise this function is meaningless. It must not be called from
* (except restarting the timer from the timer function itself), otherwise
* interrupt contexts. Upon exit the timer is not queued and the handler
* this function is meaningless. It must not be called from interrupt
* is not running on any CPU.
* contexts. Upon exit the timer is not queued and the handler is not
* running on any CPU.
*
*
* The function returns whether it has deactivated a pending timer or not.
* The function returns the number of times it has deactivated a pending
* timer.
*/
*/
int
del_timer_sync
(
struct
timer_list
*
timer
)
int
del_timer_sync
(
struct
timer_list
*
timer
)
{
{
int
i
,
ret
=
0
,
again
;
unsigned
long
flags
;
tvec_base_t
*
base
;
tvec_base_t
*
base
;
int
i
,
ret
=
0
;
check_timer
(
timer
);
check_timer
(
timer
);
del_again:
del_again:
ret
+=
del_timer
(
timer
);
ret
+=
del_timer
(
timer
);
/*
* First do a lighter but racy check, whether the
* timer is running on any other CPU:
*/
for
(
i
=
0
;
i
<
NR_CPUS
;
i
++
)
{
for
(
i
=
0
;
i
<
NR_CPUS
;
i
++
)
{
if
(
!
cpu_online
(
i
))
if
(
!
cpu_online
(
i
))
continue
;
continue
;
...
@@ -345,8 +352,33 @@ int del_timer_sync(struct timer_list *timer)
...
@@ -345,8 +352,33 @@ int del_timer_sync(struct timer_list *timer)
break
;
break
;
}
}
}
}
smp_rmb
();
/*
* Do a heavy but race-free re-check to make sure both that
* the timer is neither running nor pending:
*/
again
=
0
;
local_irq_save
(
flags
);
for
(
i
=
0
;
i
<
NR_CPUS
;
i
++
)
if
(
cpu_online
(
i
))
spin_lock
(
&
per_cpu
(
tvec_bases
,
i
).
lock
);
if
(
timer_pending
(
timer
))
if
(
timer_pending
(
timer
))
again
=
1
;
else
for
(
i
=
0
;
i
<
NR_CPUS
;
i
++
)
if
(
cpu_online
(
i
)
&&
(
per_cpu
(
tvec_bases
,
i
).
running_timer
==
timer
))
again
=
1
;
for
(
i
=
0
;
i
<
NR_CPUS
;
i
++
)
if
(
cpu_online
(
i
))
spin_unlock
(
&
per_cpu
(
tvec_bases
,
i
).
lock
);
local_irq_restore
(
flags
);
if
(
again
)
goto
del_again
;
goto
del_again
;
return
ret
;
return
ret
;
...
...
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