Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor det_ext to remove scheduler state #824

Draft
wants to merge 7 commits into
base: master
Choose a base branch
from

Conversation

corlewis
Copy link
Member

@corlewis corlewis commented Oct 28, 2024

The scheduler is now fully part of the extensible abstract specification, because we are increasingly finding properties that are not able to be reasonably specified without it. This means that there is now no non-deterministic scheduler specification and that the only slots for non-determinism are now CDT and preemption operations.

This came up due to some properties currently being proved not being true for all execution paths of the previous non-deterministic specification. Options that were considered were:
1 - move the minimal state (the current domain and tcb's domain) required for the properties currently being considered to the extensible abstract specification.
2 - move all of the scheduler state to the extensible abstract specification, the same as what has been done on the rt branch.
3 - move all state and remove the non-deterministic specification completely.
4 - add ghost state to sidestep the specific problem that we are currently encountering (it is unclear whether this would actually work).

Option 2 was chosen because it is the least blocking (although may be more annoying than some of the others), will result in the smallest diff to the rt branch, and we don't think it will be significantly more work than option 1. If we want to reason about threads in the future (e.g. liveness), we will require that this information about the scheduler state is accessible.

We are really not sure about whether moving specifically the scheduler action is the right decision, but we are moving it across because the correctness of the ready queues depends on it and any alternatives that we have thought of would be a lot of work that we do not want to do at this time.

@corlewis
Copy link
Member Author

These changes are correct enough for the AARCH64 abstract spec to still process, although of course we can't be certain that they are sufficient for our purposes until AInvs and the relevant VCPU and FPU proofs are updated. Reviews now would still be helpful to check style and to confirm that the state being moved is what we wanted. Some specific style choices made in this were to minimise the difference to the rt branch.

spec/abstract/Tcb_A.thy Outdated Show resolved Hide resolved
@Xaphiosis
Copy link
Member

Having read through it, looks good from my side. Thank you for fixing up of the style along the way!

@corlewis corlewis force-pushed the det_ext_state branch 2 times, most recently from 39e4678 to 81efd6b Compare November 8, 2024 04:59
@corlewis
Copy link
Member Author

corlewis commented Nov 8, 2024

I've updated AInvs for one architecture now. It's a big commit and will be a pain to review, but feedback now would be very helpful, so that I can clean things up before copying it to other architectures.

@corlewis corlewis force-pushed the det_ext_state branch 4 times, most recently from a9fff5a to 45bcca9 Compare November 13, 2024 10:34
corlewis and others added 7 commits November 14, 2024 21:23
The scheduler is now fully part of the extensible abstract
specification, because we are increasingly finding properties that are
not able to be reasonably specified without it. This means that there is
now no non-deterministic scheduler specification and that the only slots
for non-determinism are now CDT and preemption operations.

This came up due to some properties currently being proved not being
true for all execution paths of the previous non-deterministic
specification. Options that were considered were:
1 - move the minimal state (the current domain and tcb's domain)
required for the properties currently being considered to the extensible
abstract specification.
2 - move all of the scheduler state to the extensible abstract
specification, the same as what has been done on the rt branch.
3 - move all state and remove the non-deterministic specification
completely.
4 - add ghost state to sidestep the specific problem that we are
currently encountering (it is unclear whether this would actually work).

Option 2 was chosen because it is the least blocking (although may be
more annoying than some of the others), will result in the smallest diff
to the rt branch, and we don't think it will be significantly more work
than option 1. If we want to reason about threads in the
future (e.g. liveness), we will require that this information about the
scheduler state is accessible.

We are really not sure about whether moving specifically the scheduler
action is the right decision, but we are moving it across because the
correctness of the ready queues depends on it and any alternatives that
we have thought of would be a lot of work that we do not want to do at
this time.

Signed-off-by: Corey Lewis <corey.lewis@proofcraft.systems>
Signed-off-by: Corey Lewis <corey.lewis@proofcraft.systems>
Signed-off-by: Corey Lewis <corey.lewis@proofcraft.systems>
Signed-off-by: Corey Lewis <corey.lewis@proofcraft.systems>
…ated

This removes the threadSet loop at the end of the TCB case which previouly
needed due to ekheap in createObject in Haskell/createNewCaps in design spec.
This should simplify the proofs to some extent.

Co-authored-by: Miki Tanaka <miki.tanaka@data61.csiro.au>
Signed-off-by: Corey Lewis <corey.lewis@proofcraft.systems>
Signed-off-by: Corey Lewis <corey.lewis@proofcraft.systems>
Signed-off-by: Corey Lewis <corey.lewis@proofcraft.systems>
= state_hyp_refs_of s"
apply (rule all_ext)
apply (clarsimp simp add: state_hyp_refs_of_def obj_at_def split: option.splits)
done
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a bit repetitive, but it's probably fine, especially if you pulled it from rt

@@ -508,7 +510,7 @@ lemma dmo_scheduler_act_sane[wp]:
lemma vgic_maintenance_irq_valid_sched[wp]:
"\<lbrace>valid_sched and invs and scheduler_act_sane and ct_not_queued\<rbrace>
vgic_maintenance
\<lbrace>\<lambda>rv. valid_sched\<rbrace>"
\<lbrace>\<lambda>rv. valid_sched :: det_state \<Rightarrow> _\<rbrace>"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hang on, we can do dummy types in a type signature? how did you discover this?

@@ -232,6 +222,13 @@ locale is_extended = is_extended' +

context is_extended begin

lemma in_f_exst:
"(r, s') \<in> fst (f s) \<Longrightarrow> s\<lparr>exst := exst s'\<rparr> = s'"
apply (drule v)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oof, that name, v, also this proof is one-lineable

"cur_tcb (cdt_update f s) = cur_tcb s"
by (simp add: cur_tcb_def)

lemma cur_tcb_more_update[iff]:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do you know why this one is [iff] when all the other ones are simp?
It also looks super repetitive, they all have nearly the same proof... it almost has a crunch-like flavour, but I'm not sure we have a mechanism that can do that. Maybe scrunching the proofs into one for cur_tcb and another for valid_ioc?

apply (simp add: state_relation_def)
apply (clarsimp simp: state_relation_def)
apply (rule absSchedulerAction_correct, simp add: state_relation_def)
apply (simp add: state_relation_def)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use + to fold up subsequent repeats?

wp: switch_to_thread_invs hoare_drop_imps)

(* still true without scheduler_action s \<noteq> resume_cur_thread, but the proof for schedule_invs
will be simpler with it *)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hang on, strengthening a precondition makes the proof simpler?!

@@ -876,18 +876,17 @@ lemma threadSet_all_invs_triv':
unfolding all_invs'_def
apply (rule hoare_pre)
apply (rule wp_from_corres_unit)
apply (rule threadset_corresT [where f="tcb_arch_update (arch_tcb_context_set f)"])
apply (rule threadset_corresT [where f="tcb_arch_update (arch_tcb_context_set f)"]; simp?)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

given all resulting subgoals get simp anyway, and indent for subsequent apply hasn't changed, what does the simp? give you?

@@ -3135,7 +3137,8 @@ lemma cnc_tcb_helper:
[heap_update (registers_of_tcb_Ptr p)
(array_updates (h_val (hrs_mem hrs) (registers_of_tcb_Ptr p))
initContext_registers),
heap_update (machine_word_Ptr &(p\<rightarrow>[''tcbTimeSlice_C''])) 5])
heap_update (machine_word_Ptr &(p\<rightarrow>[''tcbTimeSlice_C''])) 5,
heap_update (machine_word_Ptr &(p\<rightarrow>[''tcbDomain_C''])) (d' :: machine_word)])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a bit confused here... this looks like the C changed somehow, but we're only changing the det_ext definitions on the abstract level, right? So why is this change needed all the way down in CRefine?

curdom \<leftarrow> curDomain;
mapM_x (\<lambda>tptr. threadSet (tcbDomain_update (\<lambda>_. curdom)) tptr) addrs;
addrs \<leftarrow> createObjects regionBase numObjects (injectKO ((makeObject ::tcb)\<lparr>tcbDomain := curdom\<rparr>)) 0;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

interesting, but it seems more consistent now to go via createObjects


lemma foldr_kh_eq:
"foldr (\<lambda>p kh. kh(p \<mapsto> ko')) ptrs kh t = Some ko \<Longrightarrow>
if t \<in> set ptrs then ko = ko' else kh t = Some ko"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if indent +1?

applied to det_ext lemmas that contain e.g. preemption_point which needs the det_ext work_units,
i.e. those will need additional locales, because 'state_ext needs to be interpreted first
into ?'state_ext.
*)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good idea, keep track of this (create an issue?) and do it as a subsequent PR to this one

lemma etcbs_of_update_state[simp]:
"get_tcb ref s = Some tcb \<Longrightarrow>
etcbs_of' (\<lambda>r. if r = ref then Some (TCB (tcb_state_update f tcb)) else kheap s r) = etcbs_of' (kheap s)"
by (auto simp: etcbs_of_update_unrelated dest!: get_tcb_SomeD)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this doesn't look like a good candidate for [simp], it both has a conditional and a very specific pattern to match on, that looks like an unfolded fun_upd; I remember on AARCH64 proofs we had issues like that with fun_upd somewhere, but don't remember where. I think we stuck with the fun_upd syntax though and prevented unfolding somewhere

apply (clarsimp simp: valid_queues_def st_tcb_at_kh_if_split)
done

lemma etcbs_of_update_bound_notification[simp]:
"get_tcb ref s = Some tcb \<Longrightarrow>
etcbs_of' (\<lambda>r. if r = ref then Some (TCB (tcb_bound_notification_update f tcb)) else kheap s r) = etcbs_of' (kheap s)"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this also looks like a strange fun_upd unfolded

lemma thread_set_priority_ct_not_in_q[wp]:
"thread_set_priority p t \<lbrace>ct_not_in_q\<rbrace>"
unfolding thread_set_priority_def thread_set_def
by (wpsimp wp: set_object_wp)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this one and thread_set_priority_neq_st_tcb_at look crunchable


lemma etcbs_of_update_tcb_time_slice[simp]:
"get_tcb ref s = Some tcb \<Longrightarrow>
etcbs_of' (\<lambda>r. if r = ref then Some (TCB (tcb_time_slice_update f tcb)) else kheap s r) = etcbs_of' (kheap s)"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

another of the fun_upd unfolded mystery

apply (rule ext, clarsimp simp: null_filter'_def map_to_ctes_delete)
apply (rule sym, rule ccontr, clarsimp)
apply (frule(2) pspace_relation_cte_wp_atI
[OF state_relation_pspace_relation])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

indent, or having [ on the prev line and indent, or try fit on same line

lemma thread_set_domain_valid_ioports[wp]:
"thread_set_domain t d \<lbrace>valid_ioports\<rbrace>"
unfolding thread_set_domain_def
by (wpsimp wp: valid_ioports_lift thread_set_caps_of_state_trivial2 simp: tcb_cap_cases_def)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I should remember this one for later when it conflicts with the changes I'm doing getting rid of valid_ioports

and caps_of_state[wp]: "\<lambda>s. P (caps_of_state s)"
and no_cdt[wp]: "\<lambda>s. P (cdt s)"
(simp: Let_def Let_def
wp: hoare_drop_imps hoare_vcg_if_lift2 mapM_wp)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a feeling that this huge crunch and the previous huge crunch have significant overlap

apply (insert assms)
apply (case_tac "injectKO v"; simp)
by (simp add: pageBits_def pteBits_def objBits_simps
split: arch_kernel_object.split)+
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this the right place for these? would Invariants_H be better?

apply (rule_tac f=g in arg_cong)
apply clarsimp
apply wpsimp+
apply simp+
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unexpected, you'd think wpsimp could clear a goal that is solved by simp?

Copy link
Member

@Xaphiosis Xaphiosis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very solid work, saw several improvements along the way, minor comments only from me. Some of the files have diffs so big they choke my browser for over a minute, not sure what can be done about that. Probably as we discussed dump the other arches in a separate PRs to the same branch?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants