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

Critique of #1853: the new get_csrs extension method is unnecessary, and has negative side effect #1863

Open
liuyu81 opened this issue Nov 28, 2024 · 3 comments

Comments

@liuyu81
Copy link

liuyu81 commented Nov 28, 2024

PR #1853 added a new get_csrs method to the public interface of extension_t, claiming to solve the alleged problem that "adding custom CSR's from extension modules was impossible". This was a false claim -- we don't need a new method for this (explained below) -- worse still, PR #1853 introduced a negative side effect causing changed CSR states to survive processor reset.

Before #1853, it was indeed possible to add custom CSR's from the extension_t::reset() method, i.e.,

void my_extension_t::reset() {
    this->p->get_state()->add_csr(...);
}

This does not require changing the public interface of extensions. And it ensures custom CSR's resume to their default states upon processor reset. We should keep it the old way.

In fact, all standard CSR's are being (re-)added during processor reset (call path processor_t::reset() -> state_t::reset() -> csr_init()). When we add custom CSR's from extension_t::reset, they equally have a chance of being reset (re-added) during processor reset (call path processor_t::reset() -> extension_t::reset()).

IMHO, what we actually need is an example of adding custom CSR's from extensions, and CI tests to make sure this works (PR #1853 has its merits in this regard). But changes to extension.h and processor.cc should perhaps be reverted.

@liuyu81
Copy link
Author

liuyu81 commented Nov 28, 2024

Also note that, the initialization of custom CSR's may require access to the processor instance (i.e. to inspect a relevant feature / state of the processor). This is why there is already extension_t::set_processor() -> extension_t::p for the extension to access processor_t *.

But the new get_csrs() method chose to take another processor_t & as input. From the PR's implementation, I learned that this was a necessary hack, because get_csrs() is invoked before extension_t::set_processor(), thus extension_t::p is nullptr from within get_csrs().

But this all smells too hacky for a public interface between spike and extensions; and it most likely will confuse extension developers who knows about extension_t::p.

@jerryz123
Copy link
Collaborator

I agree with your critique of #1853 breaking the CSR initialization pattern. As a solution, processor_t->reset() should instead call extension_t->get_csrs() and add those CSRs to the CSR map after csr_init?.

I disagree that extension_t->reset() is a sufficient interface. It is not obvious that extension_t->reset can modify other fields of state_t (and perhaps, this is a bad pattern to follow anyways).

@liuyu81
Copy link
Author

liuyu81 commented Nov 28, 2024

If an extension introduces custom CSR's to the processor, isn't it by definition modifying (extending) the processor's state?

The bright side of extension_t::reset() is that its name explicitly suggests that anything with internal states should be re-initialized from within it. The get_csrs() method, on the contrary, suggests a one-time thing, expecially when you also have get_instructions() and get_disasms().

With your proposed solution, extensions developers would have to dig into spike's internal implementation (not just public interfaces) to find out that get_csrs() will get called during processor reset (thus they can access extension_t::p from it), yet get_instructions() will get called upon initialization (with extension_t::p uninitialized). IMO, this difference in semantics would perhapse increase the burden of cognition for extension developers.

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

No branches or pull requests

2 participants