It is clearly a circular reference at the level of the interfaces. Similar to recursive data types — which have circular references at the type level — that does not necessarily mean that the instance objects are themselves are engaged in circular references (though they certainly could be).
In many circumstances (but certainly not all), there is nothing "wrong" with circular references, even though they will generally exhibit some construction & destruction ordering issues (i.e. precluding some of the instance objects involved from being immutable objects).
It can help to have a notion of parent and child. While the parent references the children, and the child reference the parent, we usually agree that deleting a child deletes only (the child itself and) the one parent-child reference (and not the parent itself), whereas deleting the parent can mean deleting not just the parent-child references, but also all its current children as well.
This means that the parent & child references are directional and asymmetrical, and in some sense, one is effectively "stronger" than the other despite the circularity, as one includes a notion of ownership that other does not.
While some databases allow us to specify this "strength" as an expression of constraint; our programming languages, by contrast, mostly do not allow us to differentiate between parent-to-child and child-to-parent references (they are both merely references). If they did allow such differentiation, we could consider parent/child and child/parent references as non-circular in the light of their asymmetrical nature.
Some reference counting algorithms break cycles via implicitly tagged or explicitly declared strong references.
In the small, cycles are not too bad when using a garbage collected language. For manual memory management, however, especially reference counting, cycles are an issue.
In the large, such as when we get to cycles in libraries (one library depends on another which depends on it...), these can be problematic in particular in regards to initialization ordering. Such problems tend to be exacerbated for circularities among operating systems components like drivers and/or subsystems: not that it cannot be done but it increases the complexity, while also hampering the ability for subsetting: creating a smaller version of the operating system for a smaller environment.